0

我正在尝试在后台读取日志文件并更新 QTextEdit. 下面是代码。但是一旦我发出信号,用户界面就会冻结。有人可以指出我在使用 QtConcurrent 时做错了什么吗?

将信号连接到插槽

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

更新日志按钮事件

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

后台任务

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
    }
}

插槽

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);
    }
}

编辑: 更改为发出信号以显示从 UpdateReaderLog() 弹出的文件打开失败

4

2 回答 2

2

请先阅读线程和事件循环

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

您在此while(!file.atEnd())循环中连续发出信号,但事件循环没有机会处理这些信号并发送到目标对象;因为这个繁忙的循环没有绘制 UI,所以你的 UI 被冻结了。

另一个问题是您的插槽在错误的线程中被调用,您需要将Qt::connect您的信号Qt::QueuedConnection作为第三个参数。它可能会解决您的问题,但请注意您的设计选择。

于 2016-05-04T05:10:28.670 回答
0

用 Qt::QueuedConnection 连接信号槽。在多线程中,你应该根据实际情况连接不同类型的信号槽。

于 2016-05-04T03:12:41.667 回答