2017-12-06 13 views
1

Qtウィンドウ(GUI)を作成し、exec()を返すMainWindowクラスにそれぞれQMainWindow::show()hide()関数を持っています。同じクラスのコンストラクタから、私は、グローバルなマウス座標を連続的に聴いているバックグラウンドで実行される別のクラスのスロット関数にスレッドを呼び出し、マウスが画面の最下部にあるときGUIメインウィンドウの表示/非表示を切り替える必要がありますx軸に沿って移動しています。ここでは、コードは次のようになります。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 
      } 

     } 


    } 
} 

私は目的のために、すべてのQtマウス機能を試してみましたが、失敗し、今私はX11のLIBを使用していますが、それは別のモジュールとして正常に動作しています。これは私の問題であり、1つにまとめて親スレッドのMainWindow::showDisplay()関数を呼び出しています。

答えて

1

これを設定したやり方では、MainWindowMouseTrackオブジェクトは別のスレッドに存在します。だからMainWindow::showDisplay()のメンバー関数をMouseTrack::trackpointer()から直接呼び出すことはお勧めできません。これはまさに信号とスロットのためのものです。

requestHide(bool)と呼ばれる信号をMouseTrackクラスに追加し、MainWindow::setVisible()スロットに接続します。 MouseTrack::trackpointer()関数では、信号をemit requestHide(hide)で出力します。 MainWindowは可視性を切り替えます。

+0

実行中の子スレッドは停止しますか?そうでなければ、シグナルを出している間、スレッドはブロック 'if(hide == 0)'の中で一時停止するか、それとも単にシグナルを出して子スレッドが実行されたままになるのでしょうか? – xcfg96

+0

@ xcfg96いいえ、信号を放射してもブロックされません。スレッドが中断されるまでwhileループで続行されます。しかし、これがループを通過して条件が有効になるたびに*信号を出すことに注意してください。また、 'hide = 1 - hide 'を実行すると、if文の条件が満たされた場合に、メインウィンドウの表示が*ループごとに切り替わる*ことを意味します。私はあなたがそのif文の条件の値に 'hide'を設定したいと思うと思います。つまり、ポジションが何かであれば隠れ、それ以外の場合は表示されます。 – bnaecker

+0

ありがとうございます。最後に、MainWindowのオブジェクトを作成する方法がわからないため、私にエラーが出ているので、 'connect'ステートメントを教えてください。私は試してみましたが失敗しました: 'connect(&mouseThread、SIGNAL(MouseTrack :: toggleMainDisplay(bool))、MainWindow、SLOT(MainWindow :: changeDisplayStatus(bool))、Qt :: DirectConnection); 上記のコメントを実装します。わかった。しかし、connect関数内の親クラスオブジェクトはどうでしょうか? – xcfg96

関連する問題