c++ - QCompleter 在 NetworkRequest 完成后无法正常工作
问题描述
与 lineEdit 关联的 Qcompleter 在 QNetworkRequest 完成的插槽中不起作用。Qcompleter 消失得很快。每次 lineEdit 中的文本更改请求时都会发送。我尝试了一个没有其他代码的演示,它也发生了。
每次编辑lineEdit中的文本时,都会将包含文本的请求发送到我的服务器。然后我想在Qcompleter中显示回复内容。但提示立即消失。
void MainWindow::onRequestFinished(QNetworkReply* reply){
QStringList stringList;
stringList << "test1" <<"test2"<<"test3";
QCompleter* completer = new QCompleter(stringList,this);
completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
ui->lineEdit->setCompleter(completer);
reply->deleteLater();
}
void MainWindow::on_lineEdit_textChanged(const QString &arg1)
{
QUrl url("http://www.google.com");
QNetworkRequest request;
request.setUrl(url);
manager->get(request);
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow){
...
this->manager = new QNetworkAccessManager(this);
connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(onRequestFinished(QNetworkReply*)));
...
}
解决方案
逻辑类似于我的旧答案,其中创建了一个模型,该模型将存储信息,这可以防止您在任何时候创建 QCompleter 避免弹出窗口消失的问题。
#include <QtWidgets>
#include <QtNetwork>
class SuggestModel: public QStandardItemModel
{
Q_OBJECT
public:
using QStandardItemModel::QStandardItemModel;
void search(const QString & text)
{
QNetworkRequest request = create_request(text);
if(m_reply)
m_reply->abort();
m_reply = manager.get(request);
connect(m_reply, &QNetworkReply::finished, this, &SuggestModel::onFinished);
QEventLoop loop;
connect(this, &SuggestModel::finished, &loop, &QEventLoop::quit);
loop.exec();
}
private Q_SLOTS:
void onFinished(){
QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
QUrl url = reply->url();
if (reply->error() == QNetworkReply::NoError) {
QVector<QString> choices;
QByteArray response(reply->readAll());
QXmlStreamReader xml(response);
while (!xml.atEnd()) {
xml.readNext();
if (xml.tokenType() == QXmlStreamReader::StartElement)
if (xml.name() == "suggestion") {
QStringRef str = xml.attributes().value("data");
choices << str.toString();
}
}
clear();
for(const QString & choice: choices)
appendRow(new QStandardItem(choice));
}
reply->deleteLater();
Q_EMIT finished();
m_reply = nullptr;
}
Q_SIGNALS:
void finished();
private:
QNetworkRequest create_request(const QString & text){
const QString suggestUrl(QStringLiteral("http://google.com/complete/search?output=toolbar&q=%1"));
QString url = suggestUrl.arg(text);
return QNetworkRequest(url);
}
QNetworkAccessManager manager;
QNetworkReply *m_reply = nullptr;
};
class SuggestCompleter: public QCompleter{
public:
SuggestCompleter(QObject *parent=nullptr):
QCompleter(parent)
{
SuggestModel *m_model = new SuggestModel(this);
setModel(m_model);
setCompletionMode(QCompleter::UnfilteredPopupCompletion);
}
QStringList splitPath(const QString &path) const override{
if(SuggestModel * m = qobject_cast<SuggestModel *>(model()))
m->search(path);
return QCompleter::splitPath(path);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLineEdit le;
le.setCompleter(new SuggestCompleter(&le));
le.show();
return a.exec();
}
#include "main.moc"
推荐阅读
- docker - docker 使用 nvidia 运行时构建
- html - Bootstrap 4 上的 Display 属性问题
- linux - PM2进程崩溃时如何自动重启?
- c# - C# 如何从外部触发 DataGridView CellFormatting 事件?
- java - 浮动操作按钮未显示在 bottomsheetfragment 折叠状态
- angular -
minDt >> 2020 年 1 月 11 日星期六 08:00:00
maxDt >> 2020 年 1 月 13 日星期三- jquery - 如何在jquery中删除最后一个动态生成的div
- oracle - 试图有递归关系
- javascript - 尝试发布到 api 路由时出现 404 错误
- r - 使用 Dplyr 查找组的最大值并在同一个表的另一列中改变结果