简体   繁体   English

在Qt中从后台更新UI(QtConcurrent)

[英]Updating UI from the background (QtConcurrent) in Qt

I am trying to read a log file in the background and update the text in QTextEdit . 我正在尝试在后台读取日志文件并更新QTextEdit的文本。 Below is the code. 下面是代码。 But once I emit the signal the UI freezes. 但是一旦发出信号,UI就会冻结。 Can someone point me out what I am doing wrong here with QtConcurrent? 有人可以指出我QtConcurrent在做什么吗?

Connect the signal to the slot 将信号连接到插槽

connect(this, SIGNAL(SignalUpdateLog(QString)),this,SLOT(SlotUpdateLog(QString)));

Update Log Button Event 更新日志按钮事件

void on_ButtonClicked()
{
   ...
   //Show busy dialog
   QtConcurrent::run(this, &ClassA::UpdateReaderLog);
 }

Background Task 后台任务

void ClassA::UpdateReaderLog()
{

    QFile file("/home/Debug.txt");
    if (file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QTextStream in(&file);
        in.setCodec("UTF-8");
        while (!file.atEnd())
        {
          emit SignalUpdateLog(in.readLine());
        }

        emit SignalUpdateLog("finishedReadingFile");
        qWarning("\nRead finished");

    }
    else
    {
        //! emit signal to show failure pop up
    }
}

The Slot 插槽

void ClassA::SlotUpdateReaderLog(QString str)
{

    if(str.contains("finishedReadingFile"))
    {
        qWarning("\nSetting reader screen");
        SetToScreen(SCREEN__READER_LOG);

        //Close the busy dialog
    }
    else
    {
        ui->textEditReaderLog->append(str);
    }
}

Edit: Changed to emit signal to show pop up from UpdateReaderLog() for file open failure 编辑:更改为发出信号以显示从UpdateReaderLog()弹出的文件打开失败

Please read Threads and Event loops first. 请先阅读线程和事件循环

while (!file.atEnd())
{
  emit SignalUpdateLog(in.readLine());
}

You are emitting signals continuously in this while(!file.atEnd()) loop but event loop has no chance to process these signals and send to the destined object; 您在while(!file.atEnd())循环中不断发出信号,但是事件循环没有机会处理这些信号并发送到目的地对象。 since UI is not being drawn because of this busy loop your UI is frozen. 由于此繁忙循环未绘制UI,因此您的UI已冻结。

Another problem is that your slot is being invoked in wrong thread, you need to Qt::connect your signal with Qt::QueuedConnection as a third argument. 另一个问题是您的插槽在错误的线程中被调用,您需要使用Qt::QueuedConnection作为第三个参数来Qt::connect您的信号。 It might fix your problem but be aware of your design choice. 它可能会解决您的问题,但请注意您的设计选择。

Connect signal-slot with Qt::QueuedConnection. 用Qt :: QueuedConnection连接信号槽。 In multi-thread, you should connect signals-slots with different types depending on practical situations . 在多线程中,应根据实际情况连接不同类型的信号插槽。

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

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