从不同线程创建 QMainWindow
Create QMainWindow from different thread
我尝试创建类似 window 池的东西。您可以在程序的任何地方使用这些 windows 来显示图形和绘图等。小部件运行良好,但目前的主要问题是创建池的尝试失败。一个非 QObject-Object 应该代表一个 QMainWindow 来切断与 Qt 的绑定。
我无法创建小部件 -> 我尝试了 invokeMethode、connect 和 QTimer,但没有任何效果。有时方法不会被调用,或者我不在 gui 线程中...有什么想法吗?
编辑 2 - 新版本:
header:
#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
#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)
并且应该创建 window 并向他展示。
Qt 将只允许您从主 GUI 线程创建小部件,这在文档中明确提到(强调我的):
As mentioned, each program has one thread when it is started. This
thread is called the "main thread" (also known as the "GUI thread" in
Qt applications). The Qt GUI must run in this thread. All widgets and
several related classes, for example QPixmap, don't work in secondary
threads. A secondary thread is commonly referred to as a "worker
thread" because it is used to offload processing work from the main
thread.
我尝试创建类似 window 池的东西。您可以在程序的任何地方使用这些 windows 来显示图形和绘图等。小部件运行良好,但目前的主要问题是创建池的尝试失败。一个非 QObject-Object 应该代表一个 QMainWindow 来切断与 Qt 的绑定。
我无法创建小部件 -> 我尝试了 invokeMethode、connect 和 QTimer,但没有任何效果。有时方法不会被调用,或者我不在 gui 线程中...有什么想法吗?
编辑 2 - 新版本:
header:
#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
#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)
并且应该创建 window 并向他展示。
Qt 将只允许您从主 GUI 线程创建小部件,这在文档中明确提到(强调我的):
As mentioned, each program has one thread when it is started. This thread is called the "main thread" (also known as the "GUI thread" in Qt applications). The Qt GUI must run in this thread. All widgets and several related classes, for example QPixmap, don't work in secondary threads. A secondary thread is commonly referred to as a "worker thread" because it is used to offload processing work from the main thread.