Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何从另一个线程关闭对话框?Qt_C++_Qt_Qthread_Qtconcurrent_Qfuture - Fatal编程技术网

C++ 如何从另一个线程关闭对话框?Qt

C++ 如何从另一个线程关闭对话框?Qt,c++,qt,qthread,qtconcurrent,qfuture,C++,Qt,Qthread,Qtconcurrent,Qfuture,我想这样处理我的按钮: 更改标签上的文字(如“请稍候…”) 从数据库下载一些数据 下载完成后,关闭此按钮所在的对话框 当我这样做时: void LoadingDialog::on_pushButton_clicked() { m_ui->labelStatus->setText("Pobieranie wysyłek..."); if(m_methodToDo == MethodToDo::LoadShipment) { if(DataManager::getManager

我想这样处理我的按钮:

  • 更改标签上的文字(如“请稍候…”)
  • 从数据库下载一些数据
  • 下载完成后,关闭此按钮所在的对话框
  • 当我这样做时:

    void LoadingDialog::on_pushButton_clicked()
    {
    m_ui->labelStatus->setText("Pobieranie wysyłek...");
    
    if(m_methodToDo == MethodToDo::LoadShipment)
    {
        if(DataManager::getManager()->loadShipments())
        {
            this->close();
        }
    }
    }
    
    标签没有改变文本,只有几秒钟的延迟(正在下载几个k记录),对话框正在关闭

    当我尝试这个:

    void LoadingDialog::changeStatus(QString status)
    {
    m_ui->labelStatus->setText(status);
    }
    
    bool LoadingDialog::load()
    {
    if(m_methodToDo == MethodToDo::LoadShipment)
    {
        if(DataManager::getManager()->loadShipments())
        {
            this->close();
        }
    }
    }
    
    void LoadingDialog::on_pushButton_clicked()
    {
    QFuture<void> future3 = QtConcurrent::run([=]() {
        changeStatus("Pobieranie wysyłek..."); // "Downloading.."
    });
    
    QFuture<void> future = QtConcurrent::run([=]() {
        load();
    });
    }
    

    有什么建议吗?

    首先,changeStatus没有阻塞,所以不要在其他线程上运行它。另一方面,如果要从另一个线程调用插槽,可以使用
    QMetaObject::invokeMethod()

    bool加载对话框::加载()
    {
    如果(m_methodToDo==methodToDo::LoadShipping)
    如果(DataManager::getManager()->LoadShippings())
    QMetaObject::invokeMethod(这个“关闭”,Qt::QueuedConnection);
    }
    无效加载对话框::在按钮上单击()
    {
    changeStatus(“Pobieranie wysyłek…”);/“下载…”
    QFuture future=QtConcurrent::run([=](){
    加载();
    });
    }
    
    首先,changeStatus没有阻塞,所以不要在其他线程上运行它。另一方面,如果要从另一个线程调用插槽,可以使用
    QMetaObject::invokeMethod()

    bool加载对话框::加载()
    {
    如果(m_methodToDo==methodToDo::LoadShipping)
    如果(DataManager::getManager()->LoadShippings())
    QMetaObject::invokeMethod(这个“关闭”,Qt::QueuedConnection);
    }
    无效加载对话框::在按钮上单击()
    {
    changeStatus(“Pobieranie wysyłek…”);/“下载…”
    QFuture future=QtConcurrent::run([=](){
    加载();
    });
    }
    
    如何将线程执行时发出的信号连接到某个插槽以执行所需操作如果按照@Spinkoo的建议使用信号和插槽,则需要确保使用队列连接进行连接。如果不这样做,您可能正在调用发出信号的同一线程中的插槽。将线程完成时发出的信号连接到某个插槽以执行所需操作如何?如果按照@Spinkoo的建议使用信号和插槽,请确保使用QueuedConnection连接。如果不这样做,则可能会调用发出信号的同一线程中的插槽。
    Cannot send events to objects owned by a different thread. Current thread 229b1178. Receiver 'Dialog' (of type 'LoadingDialog') was created in thread 18b00590
    
    bool LoadingDialog::load()
    {
        if(m_methodToDo == MethodToDo::LoadShipment)
            if(DataManager::getManager()->loadShipments())
                QMetaObject::invokeMethod(this, "close", Qt::QueuedConnection);
    }
    
    void LoadingDialog::on_pushButton_clicked()
    {
        changeStatus("Pobieranie wysyłek..."); // "Downloading.."
    
        QFuture<void> future = QtConcurrent::run([=]() {
            load();
        });
    }