How to unblock signals when mouse button is down?
-
Hi,
I would like to have QWidget with QGridLayout and many myButtons ( inherits QPushButton ) in it.
When I press random myButton, and still mouse button ( left ) will be down, and move to other button I would like to change color this two buttons.
But when I pressed left mouse button, my QWidget and my buttons don't get any signals ( like mousemoveenent or hover ). So when mouse button is down I can't do anything. Is there a solution to unblock signals?
-
Hi
You could also just make a custom widget that paint the cells as you want.#ifndef CELLWIDGET_H #define CELLWIDGET_H #include <QPainter> #include <QResizeEvent> #include <QWidget> #include <QDebug> struct Cell { QRect rect; QColor color{Qt::gray}; }; class CellWidget : public QWidget { Q_OBJECT int numCols; int numRows; int cellWidth; int cellHeight; std::vector<Cell>Cells; bool pressed = false; public: explicit CellWidget(QWidget *parent = nullptr, int nCols = 8, int nRows = 8 ) : QWidget(parent), numCols(nCols), numRows(nRows) { } void Layout() // calculate the cells { int y = 0; cellWidth = width() / numCols; cellHeight = height() / numRows; Cells.clear(); Cell tmp; for (int rows = 0; rows < numRows; ++rows) { int x = 0; for (int cols = 0; cols < numCols; ++cols) { //qDebug() << "col=" << cols << "- row=" << rows; tmp.rect.setCoords(x, y, x + cellWidth, y + cellHeight); Cells.push_back(tmp); x += cellWidth; } y += cellHeight; } } signals: protected: virtual void mouseMoveEvent(QMouseEvent *event) override { if (pressed) { for (Cell &cell : Cells) { // find cell under mouse if (cell.rect.contains(event->pos()) ) { cell.color = Qt::yellow; update(); continue; } } } } virtual void paintEvent(QPaintEvent *) override { QPainter p(this); for (const Cell &cell : Cells) { p.setBrush( cell.color); p.drawRect( cell.rect ) ; } } virtual void resizeEvent(QResizeEvent *event) override { Layout(); } virtual void mousePressEvent(QMouseEvent *) override { pressed = true; } virtual void mouseReleaseEvent(QMouseEvent *) override { pressed = false; } }; #endif // CELLWIDGET_H
-
Hi,
Not to be picky but these are events, not signals. If you want your widgets to get all mouse related events you need to use mouseTracking.
-
Did you check my suggestion ?
-
@Pl45m4 I have a QWidget ( in this example MainWindow ) with QGridLayout on it. In this QGridLayout I have many clickableLabel ( I know that I told buttons, but it is very small change ). Now I would like to do:
In green X I pressed left mouse button ( don't release! ). Now I move mouse to other labels ( red arrows ) and in blue X I release left mouse button.
I would like to get:
So I would like to change color in this labels where I pressed mouse left button, released mouse left button and which were "on the move road".
Now my clickableLabel looks like this:
myLabel::myLabel(QWidget *parent): QLabel(parent) { setMouseTracking(true); // this->setAttribute(Qt::WA_Hover, true); } void myLabel::mousePressEvent(QMouseEvent *event) { isPressed = true; QLabel::mousePressEvent(event); } void myLabel::mouseReleaseEvent(QMouseEvent *event) { QLabel::mouseReleaseEvent(event); } void myLabel::mouseMoveEvent(QMouseEvent *event) { //qInfo()<<this; QLabel::mouseMoveEvent(event); } void myLabel::hoverEnter(QHoverEvent * event) { //qDebug() << Q_FUNC_INFO << this->objectName(); } void myLabel::hoverLeave(QHoverEvent * event) { qDebug() << Q_FUNC_INFO << this->objectName(); } void myLabel::hoverMove(QHoverEvent * event) { qDebug() << Q_FUNC_INFO << this; //if(isPressed) //setStyleSheet("QLabel {background:black}"); } bool myLabel::event(QEvent * e) { qInfo()<<e->type(); // switch(e->type()) // { // case QEvent::HoverEnter: // hoverEnter(static_cast<QHoverEvent*>(e)); // return true; // break; // case QEvent::HoverLeave: // hoverLeave(static_cast<QHoverEvent*>(e)); // return true; // break; // case QEvent::HoverMove: // hoverMove(static_cast<QHoverEvent*>(e)); // return true; // break; // default: // break; // } return QWidget::event(e); }
I know that I don't change color in this code above. This is code, which I present, what I tried ( setmousetracking, hovers ). I tried with qDebug().
-
Hi
You could also just make a custom widget that paint the cells as you want.#ifndef CELLWIDGET_H #define CELLWIDGET_H #include <QPainter> #include <QResizeEvent> #include <QWidget> #include <QDebug> struct Cell { QRect rect; QColor color{Qt::gray}; }; class CellWidget : public QWidget { Q_OBJECT int numCols; int numRows; int cellWidth; int cellHeight; std::vector<Cell>Cells; bool pressed = false; public: explicit CellWidget(QWidget *parent = nullptr, int nCols = 8, int nRows = 8 ) : QWidget(parent), numCols(nCols), numRows(nRows) { } void Layout() // calculate the cells { int y = 0; cellWidth = width() / numCols; cellHeight = height() / numRows; Cells.clear(); Cell tmp; for (int rows = 0; rows < numRows; ++rows) { int x = 0; for (int cols = 0; cols < numCols; ++cols) { //qDebug() << "col=" << cols << "- row=" << rows; tmp.rect.setCoords(x, y, x + cellWidth, y + cellHeight); Cells.push_back(tmp); x += cellWidth; } y += cellHeight; } } signals: protected: virtual void mouseMoveEvent(QMouseEvent *event) override { if (pressed) { for (Cell &cell : Cells) { // find cell under mouse if (cell.rect.contains(event->pos()) ) { cell.color = Qt::yellow; update(); continue; } } } } virtual void paintEvent(QPaintEvent *) override { QPainter p(this); for (const Cell &cell : Cells) { p.setBrush( cell.color); p.drawRect( cell.rect ) ; } } virtual void resizeEvent(QResizeEvent *event) override { Layout(); } virtual void mousePressEvent(QMouseEvent *) override { pressed = true; } virtual void mouseReleaseEvent(QMouseEvent *) override { pressed = false; } }; #endif // CELLWIDGET_H