【问题标题】:QT C++. Update UI Elements from a different threadQT C++。从不同的线程更新 UI 元素
【发布时间】:2018-08-16 16:49:05
【问题描述】:

我正在尝试查找有关如何执行此操作的信息/代码,但网上的示例似乎都不适合我。

有人可以帮忙在一个单独的线程上更新 lineEdit,这样主 GUI 线程就不会挂起吗?如果我能弄清楚这一点,我可以轻松地穿线其他元素。

我有这个测试场景:

ma​​inwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class B : public QObject {
  Q_OBJECT

 signals:
  void update_signal(bool, int);

 public:
  void handleEvent();
};

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow {
  Q_OBJECT

 public:
  explicit MainWindow(QWidget *parent = nullptr);
  ~MainWindow();

 public slots:
  void m(bool, int);

 private:
  Ui::MainWindow *ui;
};

#endif

ma​​inwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow) {
  ui->setupUi(this);
}

MainWindow::~MainWindow() { delete ui; }

void B::handleEvent() {
  for (int x = 0; x < 100; x++) {
    emit update_signal(true, x);
  }
}

void MainWindow::m(bool x, int y) {
  QString tmpStr = "Rinning..." + QString::number(y);
  ui->lineEdit->setText(tmpStr);
}

ma​​in.cpp

#include <QApplication>
#include "mainwindow.h"

int main(int argc, char* argv[]) {
  QApplication a(argc, argv);
  MainWindow w;
  w.show();

  B* b = new B();
  QObject::connect(b, SIGNAL(update_signal(bool, int)), &w, SLOT(m(bool, int)),
                   Qt::QueuedConnection);

  b->handleEvent();
  return a.exec();
}

看起来像这样:

是的,我们的目标是在另一个线程上更新这个标签,而不是挂起主线程。非常感谢任何建议,为什么我的代码仍在主线程上执行。

问候。 法学。

【问题讨论】:

  • 你说的是另一个线程,但到目前为止我没有在你的代码中看到它。 SO中有很多针对类似问题的问题,您是否尝试过搜索?
  • 我做了,我复制了其中一个,它告诉我们,当我们创建和连接信号+插槽并发出函数时,它应该同时运行。这是一个信号槽机制。我是 Qt 的新手,所以任何帮助都会参与其中。
  • 你没看到他们一直在使用 QThread 吗?能指出你研究过的帖子吗?
  • 您可以从documentation example 了解基本的QThread 用法。
  • 你好像误会了什么。 Qt 不会自动为您创建任何额外的线程。此外,对于带有信号和槽的基本 Qt 线程,您将需要一个完整的 QObject 子类,您将把它移动到另一个线程,并从那里发出信号。如果这不是线程练习,您可能应该改用 QTimer。线程适用于您从同时使用的多个内核中受益(性能方面)的情况,或者如果您可以让它长时间进行计算而无需担心阻塞 GUI,代码将大大简化。

标签: multithreading qt user-interface signals slot


【解决方案1】:

您可以通过调用使您的示例在没有任何额外线程的情况下工作 QCoreApplication::processEvents(); 在handleEvent() 的循环中。这将(很快)产生对事件循环的控制并允许处理事件。在这种情况下:先前发出的信号。

对于中长期:使用QThread作为worker(逻辑),ui-thread只处理ui-handling(输入和绘画)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    • 1970-01-01
    • 2014-05-11
    • 2015-01-10
    相关资源
    最近更新 更多