问题:
在多线程 Qt 应用程序中,尝试从主线程以外的线程更新主窗口的 UI (mainwindow.ui) 会导致错误。具体来说,以下代码会失败:
mythread::run() { QPixmap i1 (":/notes/pic/4mdodiyez.jpg"); QLabel *label = new QLabel(); label->setPixmap(i1); ana->ui->horizontalLayout_4->addWidget(label); }
解决方案:
由于线程安全问题,在 Qt 中无法直接从辅助线程修改 UI。推荐的方法是将 UI 修改移动到主窗口中的插槽,并将信号从辅助线程连接到该插槽。
实现:
实现处理更新的工作类:
class GUIUpdater : public QObject { Q_OBJECT public: explicit GUIUpdater(QObject *parent = 0) : QObject(parent) {} void newLabel(const QString &image) { emit requestNewLabel(image); } signals: void requestNewLabel(const QString &); };
创建 GUIUpdater 对象并将其移动到辅助线程:
QThread *thread = new QThread(this); GUIUpdater *updater = new GUIUpdater(); updater->moveToThread(thread);
将更新程序的 requestNewLabel 信号连接到在中创建标签的槽主窗口:
connect(updater, SIGNAL(requestNewLabel(QString)), this, SLOT(createLabel(QString)));
从辅助线程调用newLabel方法触发更新:
updater->newLabel("h:/test.png");
在主窗口的槽位:
void createLabel(const QString &imgSource) { QPixmap i1(imgSource); QLabel *label = new QLabel(this); label->setPixmap(i1); layout->addWidget(label); }
这个该解决方案允许从辅助线程进行安全高效的 UI 更新,同时保持 Qt 的线程安全保证。
以上是如何从辅助线程安全地更新 Qt 主窗口?的详细内容。更多信息请关注PHP中文网其他相关文章!