Qt 小例子学习30 - QMetaObject::invokeMethod 骚操作
Widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include "worker.h"
#include <QThread>
#include <QWidget>
class Widget : public QWidget
{
Q_OBJECT
QThread workerThread;
public:
explicit Widget(QWidget *parent = nullptr) : QWidget(parent)
{
worker_create();
}
Q_INVOKABLE QString callGuiMethod(QStringList items)
{
return QInputDialog::getItem(0, "title", "label", items, 0, false);
}
~Widget()
{
workerThread.quit();
workerThread.wait();
}
public slots:
void worker_create()
{
Worker *worker = new Worker(this);
worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::started, worker, &Worker::start_work);
connect(worker, &Worker::finished, worker, &QObject::deleteLater);
connect(worker, &Worker::finished, &workerThread, &QThread::quit);
connect(&workerThread, &QThread::finished, &workerThread,
&QObject::deleteLater);
workerThread.start();
}
};
#endif // WIDGET_H
Worker.h
#ifndef WORKER_H
#define WORKER_H
#include <QDebug>
#include <QInputDialog>
#include <QStringList>
#include <QThread>
class Worker : public QObject
{
Q_OBJECT
QObject *mGui;
public:
explicit Worker(QObject *gui, QObject *parent = nullptr) : QObject(parent)
{
mGui = gui;
}
virtual ~Worker() {}
public slots:
void start_work() { ask_user(); }
void ask_user()
{
QStringList choices;
choices.append("one");
choices.append("two");
QString retVal;
for (int i = 0; i < 10; i++)
{
QMetaObject::invokeMethod(
mGui, "callGuiMethod", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(QString, retVal), Q_ARG(QStringList, choices));
qDebug() << retVal;
QThread::sleep(5);
}
}
signals:
void finished();
};
#endif // WORKER_H
main.cpp
#include "widget.h"
#include "worker.h"
#include <QApplication>
#include <QPushButton>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget widget;
widget.show();
return a.exec();
}