【发布时间】:2021-02-05 12:18:00
【问题描述】:
首先,我尝试使用thread中的setVisible()
有一个事件:
void MainWindow::OnShow(){
// Start OnShow actions
ui->LoadingBox->setVisible(true);
std::thread dThread(OnShow_threaded, ui, &(this->settingsMap));
dThread.join();
}
有一个函数OnShow_threaded:
void OnShow_threaded(Ui::MainWindow *ui, std::unordered_map<QString,QString> *settingsMap){
// Connect to server
bool hasInternet = false;
// If app doesn't have Internet access -> show offline mode
if (!hasInternet) {
ui->SettingsLabel->setVisible(true);
}
}
编译静态程序集报错时程序崩溃:
QCoreApplication::sendEvent 中的 ASSERT 失败:“无法将事件发送到 由不同线程拥有的对象。当前线程 0x0x36c56540。 接收器“WarningMsg”(类型为“QGroupBox”)在线程中创建 0x0x341c2fa0",文件 kernel\qcoreapplication.cpp,第 558 行
在线:ui->SettingsLabel->setVisible(true);
同时,动态链接时也不会出现这样的错误。
你可以在GitHub找到完整的项目
其次,我尝试使用事件。
有一个函数OnShow_threaded:
void OnShow_threaded(MainWindow* mw, Ui::MainWindow *ui, std::unordered_map<QString,QString> *settingsMap){
// Connect to server
bool hasInternet = false;
// If app doesn't have Internet access -> show offline mode
if (!hasInternet) {
MyEvent* event = new MyEvent(EventTypes::InternetConnectionError);
QCoreApplication::postEvent(mw, event);
//delete event;
//delete receiver;
}
}
有一个事件类:
#ifndef EVENTS_HPP
#define EVENTS_HPP
#include <QEvent>
#include <QString>
enum EventTypes {
InternetConnectionError,
Unknown
};
class MyEvent : public QEvent
{
public:
MyEvent(const EventTypes _type) : QEvent(QEvent::User) {_localType = _type;}
~MyEvent() {}
auto localType() const {return _localType;}
private:
int _localType;
};
#endif // EVENTS_HPP
有一个事件处理程序:
void MainWindow::events(QEvent *event)
{
if (event->type() == QEvent::User)
{
MyEvent* postedEvent = static_cast<MyEvent*>(event);
if (postedEvent->localType() == EventTypes::InternetConnectionError){
ui->WarningMsg->setVisible(true);
ui->SettingsLabel->setVisible(true);
}
}
}
传递参数:
void MainWindow::OnShow(){
// Start OnShow actions
ui->LoadingBox->setVisible(true);
std::thread dThread(OnShow_threaded, this, ui, &(this->settingsMap));
dThread.detach();
}
有一个mainwindows hpp文件:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include <QMovie>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QObject>
#include <QMessageBox>
#include <QStandardPaths>
#include <QDir>
#include <QFile>
#include <QCoreApplication>
#include <QSaveFile>
#include <QProcess>
#include <thread>
#include <chrono>
#include <unordered_map>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include "settings.hpp"
#include "events.hpp"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void OnShow();
private slots:
void SettingsLabelPressed();
void on_CloseMsgButton_clicked();
void on_Settings_SaveButton_clicked();
void on_Settings_UseTranslation_stateChanged(int arg1);
protected:
void events(QEvent* event);
private:
Ui::MainWindow *ui;
std::unordered_map<QString,QString> settingsMap;
};
void OnShow_threaded(MainWindow* mw, Ui::MainWindow *ui, std::unordered_map<QString,QString> *settingsMap);
#endif // MAINWINDOW_H
但事件没有执行。
我做错了什么?
以及如何从另一个线程正确更改 GUI?
З.Ы.对不起我的英语,我来自俄罗斯....
【问题讨论】:
-
您不能正常从自定义线程修改 GUI。您应该从 UI 线程修改您的 GUI,或使用信号/插槽从线程修改它
-
@Pat.ANDRIA 那么,我该怎么做呢?我是学生,所以我只知道来自尘土飞扬的旧教科书的信号
-
@Pat.ANDRIA 可以给代码吗?
-
仅供参考:关于Qt GUI and std::thread的另一个答案
-
@Pat.ANDRIA 我不知道如何使 QThread 发挥作用,所以如果你用它提供代码 - 它会很棒
标签: c++ qt user-interface qt5 c++17