我试图围绕现有的管理控制台应用程序包装GUI。主要功能是搜索网络设备,该网络设备被给予超时并且在超时到期之前基本上是阻塞呼叫(使用sleep来执行阻塞)。在此示例中,呼叫为this->Manager->Search(...)
。
我的问题是我希望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();
}
当我点击按钮时,QListWidget
IPList
直到超时发生后才更新(我假设直到此回调终止后)。有没有人有什么建议?我的印象是,调用ui->IPList->repaint()
会导致立即重新绘制列表。
其他信息:
答案 0 :(得分:7)
1)您无需直接调用重绘。
2)你应该异步进行搜索。这是一个很大的话题 - 你应该首先学习Qt的基础知识。
从信号和插槽开始,然后了解QThread或QtConcurrent。然后实现一个将进行搜索并发送必要信号的类:搜索开始时的第一个信号,搜索停止时的第二个信号。然后将插槽连接到此信号,并使用列表视图检查此插槽。
问题是你的“搜索管理器”会阻止Qt的事件循环。这就是为什么listview没有重新绘制的。
答案 1 :(得分: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
在另一个帖子中进行搜索。