2010-11-24 73 views
3

我試圖從QObject類的外部顯示並獲得結果消息框。我似乎能夠產生這樣的對話:顯示並從QObject外部獲取QMessageBox的結果

#include <iostream> 

#include <QApplication> 
#include <QtConcurrentRun> 
#include <QMessageBox> 

class DialogHandler : public QObject 
{ 
Q_OBJECT 

signals: 
    void MySignal(); 

public: 
    DialogHandler() 
    { 
    connect(this, SIGNAL(MySignal()), this, SLOT(MySlot())); 
    } 

    void EmitSignal() 
    { 
    emit MySignal(); 
    } 

public slots: 
    void MySlot() 
    { 
    QMessageBox* dialog = new QMessageBox; 
    dialog->setText("Test Text"); 
    dialog->exec(); 
    int result = dialog->result(); 
    if(result) 
    { 
     std::cout << "ok" << std::endl; 
    } 
    else 
    { 
     std::cout << "invalid" << std::endl; 
    } 
    } 
}; 

#include "main.moc" // For CMake's automoc 

void MyFunction(DialogHandler* dialogHandler) 
{ 
    dialogHandler->EmitSignal(); 
} 

int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 

    DialogHandler* dialogHandler = new DialogHandler; 

    MyFunction(dialogHandler); 

    return app.exec(); 
} 

要得到的結果早在MyFunction的,它似乎工作做的只是傳遞一個對象來填充其結果是這樣的:

#include <iostream> 

#include <QApplication> 
#include <QtConcurrentRun> 
#include <QMessageBox> 

class DialogHandler : public QObject 
{ 
Q_OBJECT 

signals: 
    void MySignal(int* returnValue); 

public: 
    DialogHandler() 
    { 
    connect(this, SIGNAL(MySignal(int*)), this, SLOT(MySlot(int*)), Qt::BlockingQueuedConnection); 
    } 

    void EmitSignal(int* returnValue) 
    { 
    emit MySignal(returnValue); 
    } 

public slots: 
    void MySlot(int* returnValue) 
    { 
    std::cout << "input: " << *returnValue << std::endl; 
    QMessageBox* dialog = new QMessageBox; 
    dialog->addButton(QMessageBox::Yes); 
    dialog->addButton(QMessageBox::No); 
    dialog->setText("Test Text"); 
    dialog->exec(); 
    int result = dialog->result(); 
    if(result == QMessageBox::Yes) 
    { 
     *returnValue = 1; 
    } 
    else 
    { 
     *returnValue = 0; 
    } 
    } 
}; 

#include "main.moc" // For CMake's automoc 

void MyFunction(DialogHandler* dialogHandler) 
{ 
    int returnValue = -1; 
    dialogHandler->EmitSignal(&returnValue); 

    std::cout << "returnValue: " << returnValue << std::endl; 
} 

int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 

    DialogHandler* dialogHandler = new DialogHandler; 

    QtConcurrent::run(MyFunction, dialogHandler); 

    std::cout << "End" << std::endl; 
    return app.exec(); 
} 

這看起來合理嗎?有沒有更好的方法來做到這一點?

+0

所以你使用多個線程?你可以在MyClass中創建一個QObject派生類,除了在一個插槽中顯示msgbox外別無所物,或者可以將另一個線程中的對象連接到你的小部件並在那裏顯示消息框。 – 2010-11-24 22:31:40

+0

嗯,對,我把它歸因於不在QObject類中,但是你顯然是正確的,因爲這個類不在同一個線程中。我仍然不知道如何連接信號和插槽,因爲我在這裏: Form :: MyClass :: MyFunction() { ...正在執行功能... ...發生錯誤。 ProduceMessageBox() } 由於MyClass不是QObject,它不能發射信號,所以如何讓它調用Form的函數呢? – 2010-11-25 16:32:40

回答

1

這是不可能的,就像你有它,但有一點工作可以完成。當然,一種選擇是將您的類轉換爲QObject,然後您可以發送信號。但是,這對exec期間的延遲沒有幫助。如果這是必要的,你可以有一個消息類生活在主UI線程中,但可以從其他線程調用。從其他線程調用的函數需要鎖定,產生一個信號量,並且發送一個事件給自己,同時顯示信號量和消息。然後,在customEvent(它將在UI線程中)中,您將創建消息框,執行它,並在消息框被清除後觸發信號量。

當然,如果您需要以另一種方式發送信息,事情會變得更復雜一些。然後,你需要一個完整的子系統,而不是像我在這裏描述的那樣只有一個基本的類。