[SOLVED::mostly] Problems waiting for mouse press event



  • I'm new to Qt and trying to learn a few things and i've become stuck on waiting or listening for a mouse press event.

    Here is the code that I'm working with

    The .h file

    @
    #ifndef LEARNMOUSE_H
    #define LEARNMOUSE_H

    #include <QMainWindow>

    namespace Ui {
    class LearnMouse;
    }

    class LearnMouse : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit LearnMouse(QWidget *parent = 0);
    ~LearnMouse();

    private slots:
    void on_pushButton_clicked();

    private:
    Ui::LearnMouse *ui;
    QPoint clickPoint;

    protected:

    };

    #endif // LEARNMOUSE_H
    @

    Here is the .cpp file
    @
    #include "learnmouse.h"
    #include "ui_learnmouse.h"

    LearnMouse::LearnMouse(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::LearnMouse)
    {
    ui->setupUi(this);
    }

    LearnMouse::~LearnMouse()
    {
    delete ui;
    }

    void LearnMouse::on_pushButton_clicked()
    {
    clickPoint = QCursor::pos ();

    int xPosition = pos().x();
    int yPosition = pos().y();
    
    QString xText = QString::number(xPosition);
    QString yText = QString::number(yPosition);
    
    ui->xvalueLabel->setText(xText);
    ui->yvalueLabel->setText(yText);
    
    return;
    

    }
    @

    and the .ui file if you need it
    @
    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
    <class>LearnMouse</class>
    <widget class="QMainWindow" name="LearnMouse">
    <property name="geometry">
    <rect>
    <x>0</x>
    <y>0</y>
    <width>224</width>
    <height>188</height>
    </rect>
    </property>
    <property name="windowTitle">
    <string>LearnMouse</string>
    </property>
    <widget class="QWidget" name="centralWidget">
    <widget class="QLabel" name="xvalueLabel">
    <property name="geometry">
    <rect>
    <x>30</x>
    <y>30</y>
    <width>67</width>
    <height>17</height>
    </rect>
    </property>
    <property name="text">
    <string>Xpos</string>
    </property>
    </widget>
    <widget class="QLabel" name="yvalueLabel">
    <property name="geometry">
    <rect>
    <x>130</x>
    <y>30</y>
    <width>67</width>
    <height>17</height>
    </rect>
    </property>
    <property name="text">
    <string>Ypos</string>
    </property>
    </widget>
    <widget class="QPushButton" name="pushButton">
    <property name="geometry">
    <rect>
    <x>20</x>
    <y>70</y>
    <width>181</width>
    <height>27</height>
    </rect>
    </property>
    <property name="text">
    <string>Get Mouse Coordinates</string>
    </property>
    </widget>
    </widget>
    <widget class="QMenuBar" name="menuBar">
    <property name="geometry">
    <rect>
    <x>0</x>
    <y>0</y>
    <width>224</width>
    <height>25</height>
    </rect>
    </property>
    </widget>
    <widget class="QToolBar" name="mainToolBar">
    <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
    </attribute>
    <attribute name="toolBarBreak">
    <bool>false</bool>
    </attribute>
    </widget>
    <widget class="QStatusBar" name="statusBar"/>
    </widget>
    <layoutdefault spacing="6" margin="11"/>
    <resources/>
    <connections/>
    </ui>
    @

    And finally the main.cpp file
    @
    #include "learnmouse.h"
    #include <QApplication>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    LearnMouse w;
    w.show();

    return a.exec(&#41;;
    

    }
    @

    Here is what it is currently doing. It presents a ui with 1 button and 2 labels. When you click the button it changes the labels to show the cursor x position and the cursor y position.

    Here is what I'm wanting it to do. When you click the button in the ui, i want the program to wait for the next mouse click, then change the labels with the appropriate cursor coordinates for the last mouse click.

    It's probably something simple but my research into the subject hasn't given me an answer that I can understand enough to properly implement.

    Any help is appreciated. Thanks.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Have a look at the mousePressEvent and its friends. You might also be interested in the eventFilter stuff.

    Hope it helps



  • Ok, i've given "mousePressEvent" a try and it isn't behaving exactly as I hoped.

    Here is the updated .h file
    @
    #ifndef LEARNMOUSE_H
    #define LEARNMOUSE_H

    #include <QMainWindow>
    #include <QMouseEvent>

    namespace Ui {
    class LearnMouse;
    }

    class LearnMouse : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit LearnMouse(QWidget *parent = 0);
    ~LearnMouse();

    private slots:
    void on_pushButton_clicked();

    private:
    Ui::LearnMouse *ui;
    QPoint clickPoint;
    bool getPoints;

    protected:
    void mousePressEvent(QMouseEvent *event);

    };

    #endif // LEARNMOUSE_H
    @

    And here is the updated .cpp file
    @
    #include "learnmouse.h"
    #include "ui_learnmouse.h"

    LearnMouse::LearnMouse(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::LearnMouse)
    {
    ui->setupUi(this);
    getPoints = false;
    }

    LearnMouse::~LearnMouse()
    {
    delete ui;
    }

    void LearnMouse::mousePressEvent(QMouseEvent *event)
    {
    if ((event->button() == Qt::LeftButton) && getPoints == true) {

            clickPoint = QCursor::pos ();
    
            int xPosition = pos().x();
            int yPosition = pos().y();
    
            QString xText = QString::number(xPosition);
            QString yText = QString::number(yPosition);
    
            ui->xvalueLabel->setText(xText);
            ui->yvalueLabel->setText(yText);
    
            getPoints = false;
    
    }
    

    }

    void LearnMouse::on_pushButton_clicked()
    {
    getPoints = true;

    return;
    

    }
    @

    The new behavior is that the program will wait until the mouse click after the button press before it updates the labels with the cursor position.

    The problem is that the cursor position it's using is the cursor position of the button press not the cursor position of the following mouse click. Also the program doesn't register the mousePressEvent if the cursor isn't over the widget.

    How do i get the program to give me the mouse click coordinates of the mouse click after the button press?

    How do i get the program to register the mousePressEvent when the cursor is outside the area of the widget?

    Again, thanks in advance for any help.


  • Lifetime Qt Champion

    You don't register for an event, if you want to detect this event on all your widgets, use the eventFilter approach.

    Also the QMouseEvent gives you the position of the cursor



  • Ok, i've given the eventFilter approach a try.

    Here is the updated .h file
    @
    #ifndef LEARNMOUSE_H
    #define LEARNMOUSE_H

    #include <QMainWindow>
    #include <QMouseEvent>

    namespace Ui {
    class LearnMouse;
    }

    class LearnMouse : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit LearnMouse(QWidget *parent = 0);
    ~LearnMouse();

    private slots:
    void on_pushButton_clicked();

    private:
    Ui::LearnMouse *ui;
    QPoint clickPoint;
    bool getPoints;

    protected:
    bool eventFilter(QObject *obj, QEvent *event);

    };

    #endif // LEARNMOUSE_H
    @

    here is the updated .cpp file
    @
    #include "learnmouse.h"
    #include "ui_learnmouse.h"

    LearnMouse::LearnMouse(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::LearnMouse)
    {
    ui->setupUi(this);
    getPoints = false;
    }

    LearnMouse::~LearnMouse()
    {
    delete ui;
    }

    bool LearnMouse::eventFilter(QObject *obj, QEvent *event)
    {
    if ( (event->type() == QEvent::MouseButtonPress) && getPoints == true) {

            //clickPoint = QCursor::pos ();
    
            int xPosition = pos().x();
            int yPosition = pos().y();
    
            QString xText = QString::number(xPosition);
            QString yText = QString::number(yPosition);
    
            ui->xvalueLabel->setText(xText);
            ui->yvalueLabel->setText(yText);
    
            getPoints = false;
    
    }
    // pass the event on to the parent class
    return QMainWindow::eventFilter(obj, event);
    

    }

    void LearnMouse::on_pushButton_clicked()
    {
    qApp->installEventFilter( this );
    getPoints = true;

    return;
    

    }
    @

    The program now does the same thing that the mousePressEvent method did. The program waits for the mouse click after the button press to update the label with the cursor position. The position it uses is the button press position instead of the following mouse click position.

    Doing it this way, what would the syntax look like for assigning the QMouseEvent position to my xPosition, and yPosition variables?

    Also, how do I get the program to recognize the event when the mouse click happens outside the area of the application window?

    Thanks again.


  • Lifetime Qt Champion

    Please, re-read the documentation of eventFilter to see how to properly install it.

    You can't detect a mouse press outside of your application



  • I think you need to look at QDesktop and the static functions on QCursor etc. for information on what' is happening outside your main window...

    Not sure about mouse clicks though. The QDesktop is a QWidget but I have no direct experience of using it like a normal widget :-)

    I bet someone out there in Qt land has though...



  • Ok, i did a little reading up on a bunch of things and I finally got this little sample program to do what I wanted it to do (almost). If anyone else stumbles across this thread looking for help doing the same thing here is what I had to change to get it to work.

    Modified event filter in the .cpp file
    @
    bool LearnMouse::eventFilter(QObject *obj, QEvent *event)
    {
    if ( (event->type() == QEvent::MouseButtonPress) && getPoints == true) {

            clickPoint = QCursor::pos ();  // uncomment this line
    
            int xPosition = clickPoint.x();  // change this line
            int yPosition = clickPoint.y();  // change this line
    
            QString xText = QString::number(xPosition);
            QString yText = QString::number(yPosition);
    
            ui->xvalueLabel->setText(xText);
            ui->yvalueLabel->setText(yText);
    
            getPoints = false;
    
    }
    // pass the event on to the parent class
    return QMainWindow::eventFilter(obj, event);
    

    }
    @

    I'm still very new at this and I'm sure that i've not done everything properly but the program does do what I wanted it to do, except get mouse clicks outside of the program's window area. But that is a much larger topic then collecting mouse click points in the program window area.

    Thanks to everyone that contributed.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.