0

I am trying to read a log file in the background and update the text in QTextEdit. Below is the code. But once I emit the signal the UI freezes. Can someone point me out what I am doing wrong here with 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

jxgn
  • 741
  • 2
  • 15
  • 36
  • 1
    in `ClassA::UpdateReaderLog()` you are showing a pop-up (in case of file reading failure) from a thread other than the main thread, see [this](http://doc.qt.io/qt-5/thread-basics.html#gui-thread-and-worker-thread). can you read the file successfully? – Mike May 03 '16 at 21:53
  • How big is the file? Does your application freeze indefinitely or just for a few seconds? Try debugging `QThread::currentThread` to make sure everything is run in the correct thread. Also, is `SlotUpdateReaderLog` different than `SlotUpdateLog` or is it just a typo in the question? – thuga May 04 '16 at 06:07

2 Answers2

2

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; since UI is not being drawn because of this busy loop your UI is frozen.

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. It might fix your problem but be aware of your design choice.

JamesWebbTelescopeAlien
  • 3,547
  • 2
  • 30
  • 51
0

Connect signal-slot with Qt::QueuedConnection. In multi-thread, you should connect signals-slots with different types depending on practical situations .

qd.ma
  • 26
  • 1