在 QObject 方法中生成 QWidgets
Spawn QWidgets inside a QObject's method
我现在正在制作一个程序,该程序必须管理接收请求时创建的大量QWidgets,但是我不知道如何在QObject类中创建小部件。编译器抱怨"QObject:无法为不同线程中的父级创建子级。
在谷歌上呆了一个小时,我尝试了很多方法来解决问题(这里,这里和这里(,但没有一个奏效。
以下是一些关于它的代码:
// OSD.hpp
#ifndef OSD_HPP
#define OSD_HPP
#include <QWidget>
#include <QLabel>
#include <QVBoxLayout>
class OSD : public QWidget {
Q_OBJECT
public:
explicit OSD(QWidget *parent = nullptr);
void setText(QString);
const QString getText() const;
private:
QLabel *text;
QVBoxLayout *layout1;
};
#endif // OSD_HPP
// Teller.hpp
#ifndef Teller_HPP
#define Teller_HPP
#include "OSD.hpp"
#include <QObject>
class Teller : public QObject {
Q_OBJECT
public:
explicit Teller(int port, QObject *parent = nullptr);
void SpawnNotification(std::string);
~Teller();
};
#endif // Teller_HPP
// Teller.cpp
class Worker : public QObject {
Q_OBJECT
OSD *o = nullptr;
public:
Worker(){};
~Worker() {
if (o) {
o->deleteLater();
}
};
public slots:
void process() {
o = new OSD; // Problem here
o->setText(QString("Hello"));
o->show();
QThread::sleep(1);
emit finished();
}
signals:
void finished();
};
void Teller::SpawnNotification(std::string){
QThread *thread = new QThread;
Worker *worker = new Worker();
worker->moveToThread(thread);
connect(worker, &Worker::finished, worker, &Worker::deleteLater);
connect(worker, &Worker::finished, thread, &QThread::deleteLater);
connect(thread, &QThread::started, worker, &Worker::process);
thread->start();
}
我错过了什么重要的东西吗?
在Qt中,GUI位于主线程中。Qt文档是这样说的:
GUI 线程和工作线程
如前所述,每个程序在启动时都有一个线程。此线程称为"主线程"(在Qt应用程序中也称为"GUI线程"(。Qt GUI 必须在此线程中运行。所有小部件和几个相关类(例如 QPixmap(在辅助线程中不起作用。辅助线程通常称为"工作线程",因为它用于从主线程卸载处理工作。
(链接: https://doc-snapshots.qt.io/qt5-5.12/thread-basics.html(
您需要在主线程上创建小部件,并将工作线程的信号连接到小部件的插槽。与此类似(未经测试..(:
// Must be called in main thread
void Teller::SpawnNotification(std::string){
QThread *thread = new QThread;
QWidget *widget = new QWidget(nullptr, Qt::WA_DeleteOnClose); // Top-Level window
Worker *worker = new Worker();
worker->moveToThread(thread);
connect(worker, &Worker::finished, worker, &Worker::deleteLater);
connect(worker, &Worker::finished, thread, &QThread::deleteLater);
connect(worker, &Worker::finished, widget, &QWidget::show);
//connect(worker, &Worker::dataReady, widget, &QWidget::setData); // TODO
connect(thread, &QThread::started, worker, &Worker::process);
thread->start();
}
编辑(请参阅下面的评论或 https://doc.qt.io/qt-5/qt.html#ConnectionType-enum(:
另外:Qt需要知道连接跨越不同的线程。因此,您必须在将"worker"移动到新线程或显式使用 Qt::QueuedConnection 后进行连接。
希望对您有所帮助!
相关文章:
- 删除 QSharedPointer 指向的 QObject
- QObject::连接无法将信号连接到*this*对象的插槽
- 调试符号中缺少 QObject 类信息(编辑但存在其他 Qt 类)
- QML/C++/QObject Struct Copy
- QObject::d eleteLater在我的Qt测试中没有像预期的那样调用
- 具有 QObject 继承的单例 - Qt
- QObject::连接不起作用 - 使用函数语法找不到信号
- 是否可以在单独的线程中将 QObject 设置为 QML 上下文属性?
- 智能指针作为 QObject::d eleteLater() 的替代品
- Shiboken2 qobject.h:46:10:致命:找不到'QtCore/qobjectdefs.h'文件
- 在 dll 中为 qLibrary 编译 qobject 时出错
- 将复制构造函数设置为默认值在继承自 QObject 时不起作用
- 我应该使用多个角色还是一个角色,将实际属性推迟到将数据包装/公开为其属性的QObject
- 在另一个线程上发出 QObject 信号的正确方法?
- 在 QLayout 中创建和删除自定义 QWidgets 时出现 RAM 问题
- QWidget收听其他QWidgets事件
- 为什么 QObject::d isconnect(const QMetaObject::Connection &connection) 采用 const 参数并打算修改它?
- 在 QObject 方法中生成 QWidgets
- 我可以自动处理继承 QObject 的仅标头对象吗?
- QT 库 QObject::connect: 无法连接 (null)::done() 到 MainWindow::upd