如何在Qt中循环中单独运行的子线程调用父线程函数

时间:2017-12-06 18:49:38

标签: c++ linux multithreading qt qt5

我在MainWindow类中分别有QMainWindow::show()hide()函数,用于创建Qt窗口(GUI)并返回exec()。从同一个类构造函数中,我调用了线程到另一个类槽函数,该函数在后台运行,不断地监听全局鼠标坐标,当鼠标位于屏幕底部时,它应该切换显示/隐藏GUI主窗口。沿着x轴移动。这是代码:

#include "mainwindow.hpp"
#include "Xmousetrack.hpp"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{

    MouseTrack * mT = new MouseTrack;
    mT->moveToThread(&mouseThread);

    connect(&mouseThread, SIGNAL(finished()), mT, SLOT(deleteLater()));
    connect(this, SIGNAL(signalPointer(int&,int&)), mT, SLOT(trackPointer(int&,int&)));
    mouseThread.start();
}

void MainWindow::showDisplay()
{
    MainWindow::show();
}

void MainWindow::hideDisplay()
{
    MainWindow::hide();
}


MainWindow::~MainWindow()
{
    mouseThread.requestInterruption();
    mouseThread.quit();
    mouseThread.wait();
}

// class blueprint in Xmousetrack.hpp
MouseTrack::MouseTrack()
{
    dpr = XOpenDisplay(NULL);
    if (!dpr)
    {
      std::cerr << "XOpenDisplay(0x0) returned 0x0" << std::endl;
      std::exit(EXIT_FAILURE);
    }

    Xheight = HeightOfScreen(dpr);
    Xheight -= (Xheight - 20); //the last 20 height in pixels of the screen
    xdo = xdo_new(NULL);
}

MouseTrack::~MouseTrack() { xdo_free(xdo); }


void MouseTrack::trackpointer(int &x, int &y) //slot function 
{
    xdo_get_mouse_location(xdo, &x , &y , CURRENTWINDOW); // libx11 fucntion
    prev_x = x;

    while(!QThread::currentThread()->isInterruptionRequested())
    {
        usleep(1000);
        xdo_get_mouse_location(xdo, &x , &y , CURRENTWINDOW);
        if ( abs(x - prev_x) > 10 and y >= Xheight)
        {
            hide = 1 - hide;
            if (hide == 0)
           {
            // I NEED TO CALL MainWindow::showDisplay() here 
           }

        }


    }
}

我已经尝试了所有Qt鼠标功能并且失败了,现在我正在使用X11 lib,它作为一个单独的模块工作正常。这是我的问题,结合在一起并调用父线程的MainWindow::showDisplay()函数。

1 个答案:

答案 0 :(得分:1)

您设置此方式的方式,MainWindowMouseTrack对象位于不同的主题中。因此,直接从MainWindow::showDisplay()调用MouseTrack::trackpointer()成员函数不是一个好主意。这正是信号和插槽的用途。

向您的MouseTrack课程添加一个名为requestHide(bool)的信号,并将其连接到MainWindow::setVisible()广告位。在MouseTrack::trackpointer()函数中,使用emit requestHide(hide)发出信号。然后MainWindow将切换其可见性。