【问题标题】:Create QMainWindow from different thread从不同的线程创建 QMainWindow
【发布时间】:2015-02-19 08:55:14
【问题描述】:

我尝试创建类似窗口池的东西。您可以在程序中的任何地方使用这些窗口来显示图形和绘图等。小部件运行良好,但目前的主要问题是创建池的失败尝试。一个非 QObject-Object 应该代表一个 QMainWindow 以切断与 Qt 的绑定。

我无法创建小部件 -> 我尝试了 invokeMethode、connect 和 QTimer,但没有任何效果。有时这些方法不会被调用,或者我不在 gui 线程中......有什么想法吗?

编辑 2 - 新版本:

标题:

#pragma once
#include <QMainWindow>
#include <QTimer>

class MyWindow : QObject
{
  Q_OBJECT
public:
  MyWindow();
};

class QWindowPool : public QObject
{
  Q_OBJECT
 public:
   QWindowPool();
 public slots:
  void createWindow();  
};

class QWindow : public QMainWindow
{
  Q_OBJECT
};

cpp: #包括

#include <QApplication>
#include <QTimer>
#include <QtConcurrent/qtconcurrentrun.h>

#include <iostream>
#include <future>

static QWindowPool *pool = new QWindowPool();

QWindowPool::QWindowPool() {

  // check if app is running
  if (!QApplication::instance()) {
    bool appOnline = false;
    QtConcurrent::run([&appOnline](){
      int c = 0;
      new QApplication(c, NULL);
      appOnline = true;
      qApp->exec();
    });
    while (!appOnline) {}
  }
  moveToThread(QApplication::instance()->thread());
}

void QWindowPool::createWindow() {
  printf("window created\n");
  new QWindow();
}

MyWindow::MyWindow() {
  QTimer::singleShot(0, pool, SLOT(createWindow()));
}

int main()
{
  MyWindow mw;
  std::thread t1([](){
    MyWindow mw;

    std::thread t2([](){
      MyWindow mw;
    });

    t2.join();
  });
  t1.join();

  std::cin.ignore();
  return 0;
}

现在代码做应该做的事。我可以在不同的线程中创建小部件。但是有两种情况,我会在:

  • 某人(任何想使用此库的人)在我之前创建 QApplication 并且从不调用 qApp->exec

  • 有人想用 Widget 创建自己的 UI,但在我的 qt::concurrent gui 线程中不起作用。他可能不会接受这个。

我想要的是最终应用程序: 用户应该可以在他的代码和任何线程中的任何地方编写代码:

MyWindow mw(dataToDisplay)

并且应该创建窗口并向他显示。

【问题讨论】:

    标签: c++ multithreading qt widget pool


    【解决方案1】:

    Qt 只允许您从主 GUI 线程创建小部件,这在文档中明确提到(强调我的):

    如前所述,每个程序在启动时都有一个线程。这 线程被称为“主线程”(在 Qt 应用程序)。 Qt GUI 必须在这个线程中运行。所有小部件和 几个相关的类,例如 QPixmap,在辅助中不起作用 线程。 辅助线程通常称为“工作线程” 线程”,因为它用于从主线程卸载处理工作 线程。

    【讨论】:

    • 谢谢。我希望,如果您阅读了我的问题,您会发现我知道...问题是:如何使此示例正常工作?如何将 Widget 创建放在 GUI-Thread 中?
    • @Viatorus,我可以清楚地看到您在不同的线程中创建了一个小部件。无论如何,如果您想从另一个线程调用 GUI 线程中的小部件创建,最好的方法是使用信号。例如,您在 GUI 线程中有 WindowPool 类,您可以创建 createWindow() 插槽,并将其连接到第二个线程中的信号,这样它将是线程安全的。这次我理解正确了吗?
    • 我想,你明白我的意思,但正如我已经写的那样......没有什么能像我想要的那样工作。我用更新的版本编辑了我的问题。也许你知道如何解决我的问题...
    猜你喜欢
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    相关资源
    最近更新 更多