Come ridisegnare un'altra classe Qt
Domanda
Sono un nuovo po 'in Qt ...
Ho un'applicazione GUI Qt (scritto da me), chiamiamolo QtAPP.exe Quando QtAPP.exe esecuzione, userò un QThread e QProcess per eseguire alcuni file esterno, come ad esempio player.exe (scritto in nativo C).
Ecco la mia domanda: In QtAPP.exe, esistono 2 classi, 1. QMainWindow - Nucleo di QtAPP.exe 2. QThread - Una classe thread per eseguire cose esterne
Per ora, se ho ottenuto un segnale finito () in quanto QThread, come faccio a forzare il QMainWindow venga ridisegnata automaticamente?
La speranza che qualcuno mi può mostrare alcuni suggerimenti, forse il codice di esempio :) Ogni suggerimento è benvenuto ~
Soluzione
Una soluzione potrebbe essere quella di collegare semplicemente il segnale finito () per una fessura in MainWindow cui esecuzione richiede aggiornamento (). Si noti che la consegna di questo segnale sarà asincrono perché gli oggetti mittente e il destinatario sono in diversi thread.
Ecco un esempio di lavoro:
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");
}