Systray balloon messages not appearing while an external application is being executed



  • I'm developing a GUI for an external command line application and need to display a balloon message over a systray icon before executing the command line application. I also need to frequently update a QTextEdit object while the command line app is running. The problem that I've encountered is that nothing changes in the text box and no balloon messages are displayed until after the external application completes its task.

    For example, the code below should display a balloon message next to a system tray icon.
    @
    QSystemTrayIcon::MessageIcon icon;
    icon = QSystemTrayIcon::MessageIcon(1);
    trayIcon->showMessage(tr("Title"), tr("Some message"), icon, 7000);
    @

    That code works fine unless you immediately run an external application after attempting to display the balloon message. If the code below follows the code above then no balloon message is displayed until after the external application completes its task.

    @
    FILE *fp = popen("/path/to/a/file", "r");
    if (fp == NULL)
    {
    textBox->setPlainText(tr("Error!"));
    }
    char buffer[1024];
    while(NULL != fgets(buffer, sizeof(buffer), fp))
    {
    textBox->insertPlainText(tr(buffer));
    }
    pclose(fp);
    @
    This problem is compounded by the fact that it usually takes more than 7 seconds for the external application to complete and the balloon message is only set to appear for 7 seconds. That often prevents the balloon from appearing at all.

    I'm also unable to update the QTextEdit box using insertPlainText while the external application is running. It's only after it completes that the QTextEdit box is actually updated. My goal was to display each line of text as it was output by the external application but nothing is displayed in the text box while the external app is running.

    Is there anything I can do to force the balloon message to appear before executing the external app? And how can I force the QTextEdit to display new lines of text while the external app is running?


  • Moderators

    How about using QProcess instead of this not very Qt-ish popen?

    Basically what you are doing is block till 1024 bytes are received or the external application is done. With QProcess it is a bit more straight forward to avoid this situation by connection to readyRead* signals and then getting all available output via readAll* whenever that signal is received.



  • Perfect! Thanks for the suggestion.

    After switching to QProcess the balloon message appears and the text box updates as the program is being executed.
    @
    myProcess = new QProcess(this);
    connect(myProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(updateTextBox()));
    connect(myProcess, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(endProcess(int,QProcess::ExitStatus)));

    QSystemTrayIcon::MessageIcon icon;
    icon = QSystemTrayIcon::MessageIcon(1);
    trayIcon->showMessage(tr(""), tr("Process started."), icon, 5000);

    myProcess->start(file, options);

    void My_GUI::updateTextBox()
    {
    QByteArray result = myProcess->readAllStandardOutput();
    textBox->insertPlainText(result);
    }

    void My_GUI::endProcess(int exitCode, QProcess::ExitStatus exitStatus)
    {
    myProcess->close();
    QSystemTrayIcon::MessageIcon icon;
    icon = QSystemTrayIcon::MessageIcon(1);
    trayIcon->showMessage(tr(""), tr("Process completed."), icon, 5000);
    }
    @


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.