繁体   English   中英

QNetworkAccessManager即使在另一个线程中也会冻结GUI

[英]QNetworkAccessManager freezes GUI even when in another thread

当我的程序打开时,通过QNetworkAccessManager::connectToHostEncrypted()与我的服务器建立连接,该连接在MainWindow的构造函数中调用。 这将冻结GUI线程,并导致明显的延迟,直到连接完成。 (有时超过一整秒钟)

由于我的程序在启动时会逐渐淡入,因此使该问题更加严重,因此,在GUI线程被阻止的情况下,直到连接完成后才会开始淡入。 在默认的Qt项目中,这可以通过其他方式看到,例如未绘制小部件。

为了使GUI线程继续运行,我将QNetworkAccessManager移到了一个完全不同的线程中, QThread认为这可以解决问题,但是GUI线程仍然冻结。 这对我来说毫无意义。

这是一个最小编译的示例项目。

主窗口

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QNetworkAccessManager>
#include <QThread>

class Connection : public QNetworkAccessManager
{
    Q_OBJECT
public:
    Connection(QObject *parent) : QNetworkAccessManager(parent){}

public slots:
    void openConnection(){
        connectToHostEncrypted("https://www.url.com");
    }

signals:
    void closeThread(bool);
};


namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QThread *connectionThread;
    Connection *connection;
};

#endif // MAINWINDOW_H

主窗口

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

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

    connection = new Connection(this);

    connectionThread = new QThread();
    connection->moveToThread(connectionThread);
    connect(connectionThread, SIGNAL(started()), connection, SLOT(openConnection()));
    connect(connection, SIGNAL(closeThread(bool)), connectionThread, SLOT(quit()));
    connect(connectionThread, SIGNAL(finished()), connectionThread, SLOT(deleteLater()));

    connectionThread->start();
}

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

这个示例项目创建一个Connection实例,它是QNetworkAccessManager的子类,然后我通过moveToThread()移到另一个线程。 这就是我处理所有工作线程的方式。

发出线程的start()信号时, openConnection()调用GUI线程冻结的connectToHostEncrypted()

我尝试仅调用常规HTTP请求,但是问题仍然存在,因为仍需要进行初始连接。

即使连接是在另一个线程中完成的,GUI线程怎么仍然冻结?

尝试使用:

connect(connectionThread, SIGNAL(started()), connection, SLOT(openConnection(),Qt::QueuedConnection);

问题是我将this作为父级传递给Connection实例,这意味着无法完成moveToThread() 我只需要检查输出日志就可以看到它,但是我一定错过了!

通过删除该父对象,该连接现在位于其自己的线程中。

我通过在openConnection()调用内调用QThread::sleep(3)进行了进一步测试,但仍然没有延迟。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM