Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QSplitter - change grab region size or add a custom knob



  • I have a QSplittler working in my app but I find that on very large, high pixel density monitors, and especially on touch screens, it is very hard to grab the splitter and start a resize operation with your finger. When the pixel density is high, and the splitter is only a few pixels wide, it is hard to touch on it and start a drag the splitter bar.

    I would rather not resize the width of the bar to make it wider and therefore easier to hit, as I am trying to compare things side by side and would like to keep the bar as narrow as possible.

    I can think of two solutions:

    1. Find some way to make the hit testing that is being done internally by QT so that the QSplitter bar has a much wider width when testing for a hit than its actual width. I think QT is doing this, already, but I would like to make the "slop" distance even larger if the screen is very high density or if I know it is a touch screen (fat fingers).

    2. Add some sort of larger, graphic control handle or knob in the middle of the slider like this:
      ---------------O----------------- (except my slider is vertical). This knob should collapse to half its size if the splitter is all the way to one side.

    Any ideas?

    Thank you!


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Would QSplitte::handleWith property do the job ?


  • Lifetime Qt Champion

    Hi and welcome to the forums
    You can do like this for a slightly crude version

    // subclass a splitterhandle so we can use enter and leave events.
    class  MySplitterHandle : public QSplitterHandle
    {
        Q_OBJECT
        int handleWidthOrg;
    public:
        explicit MySplitterHandle(Qt::Orientation o, QSplitter *parent) : QSplitterHandle(o, parent)
        {
    
            handleWidthOrg = splitter()->handleWidth(); // store default value
    
        }
    protected:
    
        void paintEvent(QPaintEvent *) override
        {
          QSplitterHandle::paintEvent(e);
          QPainter p(this);
          p.drawRect(0,0, width()-1, height()-1); // this is just to see it more clearly
        }
    
        virtual void enterEvent(QEvent *) override
        {
            splitter()->setHandleWidth(handleWidthOrg * 3); // expand it
        }
    
        virtual void leaveEvent(QEvent *) override
        {
            splitter()->setHandleWidth(handleWidthOrg); // restore normal size
        }
    };
    
    // subclass a splitter so we can return our handle
    class MySplitter : public QSplitter
    {
    public:
        MySplitter(QWidget *parent = nullptr) : QSplitter(parent) {}
    protected:
        virtual QSplitterHandle *createHandle() override
        {
            return new MySplitterHandle(orientation(), this ); // return our handle
        }
    };
    

    alt text



  • @SGaist Thanks for your reply. I can change the handle width to make it easier to graph with a touch screen, but I would like to keep it at thin as possible and only and a wider graphic element like a circle in the middle of the line. Something like this: f874cea1-ac40-4d65-8dea-6dd0a814e46c-image.png I can see that this would be quite different behavior, so failing that I would like to simply make the grab region of the splitter handle much large than its width on screen so it is easier to "hit" with your finger.



  • @mrjj Thanks for this suggestion and code! This would sort of work, but again I am talking about a touch screen and unlike a mouse, one does not hover over the controls and then click, there is only the touch (no hover events with a touchscreen). The two panels of the splitter are QGraphicsViews and if I touch and miss the narrow slider then they capture the events (as they should). I would like to be able to have the Qt window manager make the grab region of the slider larger than its size on screen. BTW I notice on this forum the exact same UI element I am trying to get in Qt. When you reply, to a message, you can move the reply panel up and down on the page with either the splitter line or the black circle: 9ff4f6d0-7580-4dc0-9833-7f75b8e616d4-image.png


  • Lifetime Qt Champion

    @Doug-Wood
    Hi
    Sorry my bad. I miss the touch part.
    No hover in that use case.

    The issues is that the handle is a widget and its not possible to draw outside its
    area in any good way.

    However, i was wondering if an event filter could be used to look at mouseMove event and expand the "trigger" zone.


Log in to reply