I am trying to implement a snap-to-grid/snap-to-guideline functionality to a QSplitter
.
The idea is:
- Integer values are set onto the
QSplitter
(or possibly its parent widget or another ancestor) representing vertical/horizontal lines or a grid. - Moving the splitter’s handle works as usual when the mouse button (LMB) is pressed…
- … except when the mouse cursor comes within a few pixels of a line, in which case the handle is moved to it and, importantly, stays stuck to it.
- When the mouse is moved away from the line (while the LMB is still held down), the handle is moved back to where the mouse is and the tracking resumes.
I was expecting such functionality to already exist in Qt but I could not find a clue in the assistant.
On a related note, QSplitter
seems to ignore the size increment values of a widget, although it does respect the minimum size.
My PoC code is as follows; the middle widget in the splitter had a custom paint event to make it easier to track its width:
#include <QtWidgets/QApplication>
#include <QtGui/QPainter>
#include <QtWidgets/QSplitter>
#include <QtWidgets/QVBoxLayout>
class MyWidget : public QWidget {
public:
MyWidget(QWidget* parent = nullptr) : QWidget(parent)
{
setMinimumWidth(60);
setSizeIncrement(QSize(20, 0));
}
protected:
void paintEvent(QPaintEvent*) override
{
QPainter painter(this);
for (int x = 10; x < width(); x += 20) {
painter.drawLine(x, 0, x, height());
}
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
w.setMinimumSize(800, 600);
QVBoxLayout l;
QSplitter splitter(&w);
l.addWidget(&splitter);
w.setLayout(&l);
MyWidget constrainedWidget(&splitter);
splitter.addWidget(new QWidget(&splitter));
splitter.addWidget(&constrainedWidget);
splitter.addWidget(new QWidget(&splitter));
w.setStyleSheet("QFrame { background: dodgerblue; }");
w.show();
return a.exec();
}
Assuming I have not missed a class/method in the documentation, what would the best way to go with the implementation of this functionality be?