tags:

views:

231

answers:

1

Hi all, I'm a new bit in Qt...

I have a Qt GUI application (written by me), let's call it QtAPP.exe When QtAPP.exe running, I will use a QThread and QProcess to execute some external file, such as player.exe (written in native C).

Here's my question: In QtAPP.exe, there are 2 classes, 1. QMainWindow - Core of QtAPP.exe 2. QThread - A thread class to execute external things

For now, if I got a finished() signal in that QThread, how do I to force the QMainWindow to repaint itself ?

Hope somebody can show me some tips, maybe sample code :) Any suggestion are welcome~

+1  A: 

One solution would be to simply connect the finished() signal to a slot in MainWindow whose implementation calls update(). Note that delivery of this signal will be asynchronous because the sender and receiver objects are in different threads.

Here is a working example:

main.cpp

#include <QtGui/QApplication>
#include "stuff.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MainWindow w;
    w.show();
    return app.exec();
}

stuff.h

#ifndef STUFF_H
#define STUFF_H

#include <QtGui/QMainWindow>
#include <QtCore/QThread>

class QLabel;

class Thread : public QThread
{
    Q_OBJECT
public:
    Thread(QObject *parent);
    void run();

private:
    void startWork();

signals:
    void workFinished();
};

class MainWindow : public QWidget
{
    Q_OBJECT
public:
    MainWindow();

public slots:
    void startWork();
    void workFinished();

private:
    QLabel* m_label;
    Thread* m_thread;
};

#endif

stuff.cpp

#include <QtCore/QTimer>
#include <QtCore/QMutex>
#include <QtCore/QWaitCondition>
#include <QtGui/QVBoxLayout>
#include <QtGui/QPushButton>
#include <QtGui/QLabel>
#include "stuff.h"

#include <QDebug>

// Global variables used for ITC
QWaitCondition buttonPressed;
QMutex mutex;

Thread::Thread(QObject *parent)
    :   QThread(parent)
{

}

void Thread::run()
{
    qDebug() << "Thread::run" << QThread::currentThreadId();
    while (1) {
        mutex.lock();
        buttonPressed.wait(&mutex);
        mutex.unlock();
        startWork();
    }
}

void Thread::startWork()
{
    qDebug() << "Thread::startWork" << QThread::currentThreadId();
    // Simulate some long-running task
    sleep(3);
    // Emit a signal, which will be received in the main thread
    emit workFinished();
}


MainWindow::MainWindow()
    :   m_label(new QLabel(this))
    ,   m_thread(new Thread(this))
{
    QPushButton *button = new QPushButton("Start", this);
    connect(button, SIGNAL(pressed()), this, SLOT(startWork()));

    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->addWidget(button);
    layout->addWidget(m_label);
    setLayout(layout);

    // Create connection across thread boundary
    connect(m_thread, SIGNAL(workFinished()), this, SLOT(workFinished()));

    m_thread->start();
}

void MainWindow::startWork()
{
    // Signal the thread to tell it that the button has been pressed
    mutex.lock();
    m_label->setText("Started");
    buttonPressed.wakeAll();
    mutex.unlock();
}

void MainWindow::workFinished()
{
    qDebug() << "MainWindow::workFinished" << QThread::currentThreadId();
    m_label->setText("Finished");
}
Gareth Stockwell
Please check my sample code above, due to not allow too much word in 1 comment...What is the XXXX be, how do I instance of MainWindow class ?Or the way I'm thinking about is totally incorrect ?Thanks to your suggestion, but I still don't understand how to connect signal to the slot which in other class..@@"May you give some more tips about this ?
RR
Thank you, I did catched finished() signal and pass to other class, but fail to repaint :((That's another story...)Still thank you for help me to solve problem :)
RR