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

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?


  • Lifetime Qt Champion

    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
    
    

    alt text


  • Lifetime Qt Champion

    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.




  • Lifetime Qt Champion

    Did you check my suggestion ?



  • @SGaist I tried mouseTracking, but still don't get events when button is down.



  • @qwe3

    What you have done so far? How does your myButton class look like?



  • @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:

    first.png

    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:

    second.png

    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().


  • Lifetime Qt Champion

    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
    
    

    alt text


Log in to reply