2017-12-06 7 views
1

Qt 윈도우 (GUI)를 생성하고 exec()을 반환하는 MainWindow 클래스에 각각 QMainWindow::show()hide() 함수가 있습니다. 동일한 클래스 생성자에서 전역 마우스 좌표를 지속적으로 수신하는 배경에서 실행되는 다른 클래스 슬롯 함수에 스레드를 호출했으며 마우스가 화면 맨 아래에있을 때 GUI 주 창 표시/숨기기를 전환해야합니다. x 축을 따라 움직입니다. 여기에 코드입니다 : 나는이 목적을 위해 모든 Qt는 마우스 기능을했으나 실패하고 지금은 X11 lib 디렉토리를 사용하고있다Qt에서 반복적으로 실행되는 자식 스레드에서 부모 스레드 함수를 호출하는 방법

#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 
      } 

     } 


    } 
} 

과 별도의 모듈로 작동합니다. 이것은 모든 것을 하나로 결합하고 부모 스레드의 MainWindow::showDisplay() 함수를 호출하는 것에 대한 내 문제입니다.

답변

1

설정 한 방식대로 MainWindowMouseTrack 개체는 서로 다른 스레드에 있습니다. 따라서 직접 에서 MainWindow::showDisplay() 멤버 함수를 호출하는 것은 좋은 생각이 아닙니다. 이것은 정확히 신호와 슬롯을위한 것입니다.

클래스에 신호를 추가하십시오 (예 : requestHide(bool)). MainWindow::setVisible() 슬롯에 연결하십시오. MouseTrack::trackpointer() 함수에서 emit requestHide(hide)으로 신호를 내 보냅니다. 그러면 MainWindow이 표시 여부를 토글합니다.

+0

실행중인 하위 스레드가 중지됩니까? 그렇지 않다면, 신호를 내보내는 동안 스레드는 블록'if (hide == 0)'안에서 멈추거나 신호를 방출하고 자식 스레드는 실행 상태를 유지합니까? – xcfg96

+0

@ xcfg96 아니요, 신호를 내보내는 것이 차단되지 않습니다. 스레드가 인터럽트 될 때까지 while 루프를 계속 진행합니다. 그러나 이것이 매회 루프를 통과하고 조건이 유효 할 때마다 신호를 방출한다는 것을 명심하십시오. 또한, 'hide = 1 - hide'를 실행하면 if 문 조건이 충족되면 루프를 통해 매번 * 토글됨을 의미합니다. 그 if-statement의 조건 값에'hide'를 설정하기를 원한다고 생각합니다. 즉, 위치가 뭔가가 있으면 숨기고, 그렇지 않으면 숨길 수 있습니다. – bnaecker

+0

감사. 마지막으로 MainWindow의 객체를 생성하는 방법을 모르기 때문에 광산에서 오류를 발생시키는 것처럼'connect' 문을 주실 수 있습니까? 나는 시도했으나 오류가 발생했다 :'connect (& mouseThread, SIGNAL (MouseTrack :: toggleMainDisplay (bool)), MainWindow, SLOT (MainWindow :: changeDisplayStatus (bool)), Qt :: DirectConnection); 위의 주석을 구현할 것이다. . 알았다. 하지만 연결 함수 내부의 부모 클래스 객체는 어떻습니까? – xcfg96