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:
-
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).
-
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!
-
-
Hi and welcome to devnet,
Would QSplitte::handleWith property do the job ?
-
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 } };
-
@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: 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:
-
@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.