我創建了一個應用程序,我想在應用程序打開項目時添加加載屏幕,因爲項目的加載可能很長,有時候,gui會阻止用戶可以認爲存在崩潰。Qt在打開項目時添加加載小部件屏幕
因此,我嘗試與QThread,閱讀文檔和「解決」在這個論壇上的例子,但沒有做什麼,我不能讓它工作。
我有一個MainWindow類與GUI優惠和這個類是一個我在主函數創建:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
然後,我有: mainwindow.h
class MyThread;
class MainWindow : public QMainWindow
{
Q_OBJECT
...
private :
Controller *controller;//inherits from QObject and loads the project
QList<MyThread*> threads;
public slots :
void animateLoadingScreen(int inValue);
}
主窗口。 cpp
MainWindow::MainWindow(...)
{
controller=new Controller(...);
threads.append(new MyThread(30, this));
connect(threads[0], SIGNAL(valueChanged(int)), this, SLOT(animateLoadingScreen(int)));
}
void MainWindow::animateLoadingScreen(int inValue)
{
cout<<"MainWindow::animateLoadingScreen"<<endl;
widgetLoadingScreen->updateValue(inValue);//to update the animation
}
void MainWindow::openProject()
{
widgetLoadingScreen->show()://a widget containing a spinner for example
threads[0]->start();//I want to launch the other thread here
controller->openProject();
threads[0]->exit(0);//end of thread so end of loading screen
}
MyThread.h
class MyThread : public QThread
{
Q_OBJECT;
public:
explicit MyThread(int interval, QObject* parent = 0);
~MyThread();
signals:
void valueChanged(int);
private slots:
void count(void);
protected:
void run(void);
private:
int i;
int inc;
int intvl;
QTimer* timer;
};
MyThread.cpp
MyThread::MyThread(int interval, QObject* parent): QThread(parent), i(0), inc(-1), intvl(interval), timer(0)
{
}
void MyThread::run(void)
{
if(timer == 0)
{
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(count()));
}
timer->start(intvl);
exec();
}
void MyThread::count(void)
{
if(i >= 100 || i <= 0)
inc = -inc;
i += inc;
emit valueChanged(i);
}
當我執行的應用程序,並單擊打開按鈕,啓動主窗口:: openProject(),我得到:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is MyThread(0x5463930), parent's thread is QThread(0x3cd1f80), current thread is MyThread(0x5463930)
MainWindow::animateLoadingScreen
MainWindow::animateLoadingScreen
....
MainWindow::animateLoadingScreen
MainWindow::animateLoadingScreen
(and here the controller outputs. and no MainWindow::animateLoadingScreen anymore so the widget loading screen is never animated during the opening of the project)
那麼做我必須做什麼,我必須在MyThread類中放置什麼,如何將其信號鏈接到MainWindow以更新加載屏幕。我認爲在MainWindow中創建的widgetLoadingScreen可能存在問題,因此如果由於打開而導致MainWindow被阻塞,那麼widgetLoadingScreen不能更新,因爲它位於處理GUI的MainWindow線程中?
我讀: http://www.qtcentre.org/wiki/index.php?title=Updating_GUI_from_QThread 但是那一個,我在運行時遇到錯誤消息,這是一個我在我上面給出 QObject的代碼中使用:無法爲父母是在不同的線程創建的兒童。 (Parent是MyThread的(0x41938e0),父母的線程的QThread(0x1221f80),當前線程是MyThread的(0x41938e0)
我想,太: How to emit cross-thread signal in Qt? 但是,即使我沒有在運行時錯誤消息對於未更新的動畫也是如此
我完全失去了,我不認爲在主線程打開項目時在線程中加載屏幕是一件難事。
您的帖子甚至沒有做任何事情。不用新線程就可以使用'QTimer'。繁重的處理是你需要轉移到一個新的線程,這對我來說似乎是在你的Controller類中。 – thuga
這又是一個*** [我的子類的QThread做多線程,它不工作(http://codethis.wordpress.com/2011/04/04/using-qthread-without-subclassing/)***問題 – UmNyobe
@thuga從我在http://www.qtcentre.org/wiki/index.php?title=Updating_GUI_from_QThread中理解的內容來看,它是使run函數執行發出信號的count函數的計時器。我不能將繁重的過程移動到新的線程,它會更加複雜,因爲加載過程會發出多個信號,...更新其他gui類。這就是爲什麼我想在另一個線程中創建一個簡單的加載控件,當我需要很長的加載過程時,我可以運行它。 – SteveTJS