2013-07-05 4 views
1

Я пытаюсь обернуть графический интерфейс вокруг существующего приложения консоли управления. Основная функция - поиск сетевых устройств, которым задан тайм-аут и по сути является блокирующим вызовом до истечения таймаута (использование сна для блокировки). В этом примере вызов равен this->Manager->Search(...).Принудительное обновление QTListWidget для добавления/удаления элементов

Моя проблема в том, что я хочу, чтобы QListWidget отображал «Поиск ...» во время поиска, а затем обновлялся с результатами по завершении поиска. Мой на клик код кнопки Search выглядит следующим образом:

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

Когда я нажал на кнопку, то QListWidgetIPList не обновляется до тех пор, после того, как тайм-аут имеет место (и я предполагаю, что до тех пор, после того, как этот обратный вызов не прекращается) , У кого-нибудь есть предложения? У меня создалось впечатление, что вызов ui->IPList->repaint() вызовет немедленную перерисовку списка.

Дополнительная информация:

  • QT версии 5.1.0 32-Bit
  • Составлено с использованием VS2012
  • Запуск на Win7 Pro 64-бит (но быть портирована на OSX и Linux, так что ничего выиграть -специфические, пожалуйста)
+1

Если вы заблокировали этот-> Менеджер-> Поиск, вы должны запустить в другом потоке ... – Trompa

ответ

7

1) Вам не нужно переписывать напрямую.

2) Вы должны выполнить поиск асинхронно. Это большая тема - сначала вы должны изучить основы Qt.

Начните с сигналов и слотов, а затем узнайте о QThread или QtConcurrent. Затем реализуем класс, который будет выполнять поиск и отправку необходимых сигналов: первый сигнал при запуске поиска, второй сигнал - при остановке поиска. Затем подключите слоты к этим сигналам и работайте со списком в этом слоте.

Проблема в том, что ваш менеджер поиска блокирует цикл событий Qt. Вот почему listview не перекрашивается.

+0

Голосовать. Поскольку это, вероятно, будет одним вызовом, самой быстрой реализацией будет Qt :: Concurrent. Быстрый обзор был бы следующим: http://qt-project.org/doc/qt-4.8/thread-basics.html –

+0

Спасибо, Дмитрий, это делает все намного яснее, хотя это не тот ответ, на который я надеялся. Я надеялся, что перерисовка произошла в другом пространстве нитей для выполнения обратных вызовов события, но я явно надеялся быть более ленивым, чем это было возможно. Код менеджера уже использует Boost для выполнения всех сетевых операций ввода-вывода, поэтому я могу создать рабочий поток там и зарегистрировать обратный вызов до уровня Q. Таким образом, у других пользователей моей библиотеки-менеджера будет возможность асинхронного вызова как-хорошо. – OcularProgrammer

1

Вам нужна система слотов сигнала, потому что ваш поиск блокируется. В идеале вы должны выполнить поиск в новом потоке. Однако вы можете обмануть с 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); 
    } 
} 

В идеале вы хотели бы, чтобы Manager->Search излучать сигнал, а затем использовать QtConcurrent::run сделать поиск в другом потоке.

+0

Большое спасибо за ответ Фил. Мне нравится обходной путь, но для этого приложения мне действительно нужно укусить пулю и выполнить соответствующую поточную реализацию класса менеджера.На самом деле интересный ответ, я, очевидно, гораздо больше узнаю о возможностях сигнализации Qt. – OcularProgrammer

Смежные вопросы