Question

I'm attempting to wrap a GUI around an existing management console app. The main function is to search for network devices, which is given a timeout and is essentially a blocking call until the timeout has expired (using sleep to do the blocking). In this example the call is this->Manager->Search(...).

My issue is that I want the QListWidget to display "Searching..." while the search is taking place, and then update with the results at the completion of the search. My on-click code for the Search button is as follows:

void ManagerGUI::on_searchButton_clicked()
{
  ui->IPList->clear();
  new QListWidgetItem(tr("Searching..."), ui->IPList);
  ui->IPList->repaint();
  this->Manager->Search(static_cast<unsigned int>(this->ui->searchTime->value()*1000.0));
  ui->IPList->clear();
  if(this->Manager->GetNumInList() != 0)
    this->displayFoundInList(this->Manager->GetFoundList());
  else
    new QListWidgetItem(tr("No Eyes Found"), ui->IPList);
  ui->IPList->repaint();
}

When I hit the button, the QListWidget IPList does not update until after the timeout has taken place (and I assume until after this callback has terminated). Does anyone have any suggestions? I was under the impression that calling ui->IPList->repaint() would cause an immediate redraw of the list.

Additional info:

  • QT Version 5.1.0 32-Bit
  • Compiled using VS2012
  • Running on Win7 Pro 64-bit (but to be ported to OSX and Linux, so nothing win-specific please)
Was it helpful?

Solution

1) You don't need to call repaint directly.

2) You should do your search asynchronously. It is big topic - you should learn basics of Qt first.

Start with signals and slots and then learn about QThread or QtConcurrent. Then implement a class that will do searching and send necessary signals: first signal on search start, second signal - on search stop. Then connect slots to this signals and work with your list view insine this slots.

Problem is that your "Search manager" blocks Qt's event loop. Thats why listview does not repainted.

OTHER TIPS

You need a signal slot system because your search is blocking. Ideally you should do the search in a new thread. However you can cheat with a processEvents()

void ManagerGUI::on_searchButton_clicked()
{
  ui->IPList->clear();
  new QListWidgetItem(tr("Searching..."), ui->IPList);
  emit signalStartSearch();
}

void ManageGUI::slotStartSearch()
{
  // Process any outstanding events (such as repainting)
  QCoreApplication::processEvents();
  this->Manager->Search(static_cast<unsigned int>(this->ui->searchTime->value()*1000.0));
  emit signalSearchCompleted();
}

void ManagerGUI::slotSeachCompleted()
{
  ui->IPList->clear();
  if(this->Manager->GetNumInList() != 0) {
    ui->IPList->setUpdatesEnabled(false);
    this->displayFoundInList(this->Manager->GetFoundList());
    ui->IPList->setUpdatesEnabled(true);
  } else {
    new QListWidgetItem(tr("No Eyes Found"), ui->IPList);
  }
}

Ideally you would want the Manager->Search to emit the signal and then use QtConcurrent::run to do the search in another thread.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top