Accessing QT GUI from CALLBACK

684 views Asked by At

I am catching all mouse events happening in my program with a windows hook:

#include <Windows.h>
#pragma comment(lib, "user32.lib")
HHOOK hHook = NULL;
using namespace std;

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {   
    switch( wParam )
    {
      case 0x201:  qDebug() << "Left click"; // Left click
    }
    return CallNextHookEx(hHook, nCode, wParam, lParam);
}

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
hHook = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, NULL, 0);
if (hHook == NULL) {
    qDebug() << "Hook failed";
}
ui->setupUi(this);
}

I want to put the data received inside MouseProc() into a label on my QT GUI. How can I access it from there? This for example doesn't work:

ui->label1->setText("Left click");
1

There are 1 answers

0
vahancho On BEST ANSWER

First of all I would add new function to your MainWindow class, that will return the pointer to the label you want to update:

QLabel *MainWindow::label() const
{
    return ui->label1;
}

and than I would rewrite the callback function in the following way:

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {   
    switch( wParam )
    {
        case 0x201:
            qDebug() << "Left click"; // Left click
            QWidgetList wl = QApplication::topLevelWidgets ();
            foreach (QWidget *widget, wl) {
                if (MainWindow *mw = qobject_cast<MainWindow *>(widget)) {
                    mw->label()->setText("Left click");
                    break;
                }
            }
    }
    return CallNextHookEx(hHook, nCode, wParam, lParam);
}

Alternatively, of course, you can use global variables etc., but I find this solution much more elegant.

UPDATE:

Another improvement, that looks even better to me, is just hiding the label information and update mouse click status with such function:

void MainWindow::setMouseStatus(const QString &text)
{
    ui->label1->setText(text);
}

Now you can call it from the callback as:

[..]
mw->setMouseStatus("Left click");