简体   繁体   中英

QCompleter doesn't work properly with NetworkRequest finished

Qcompleter which is associated with a lineEdit doesn't work in the slot of a QNetworkRequest finished.The Qcompleter disappeared quite quickly.Each time the text in lineEdit changed a request was send.I tried a demo without other code,it also occured.

Every time the text in lineEdit was edit,a request contains the text will be send to my server.And then I want to show the content in reply in a Qcompleter.But the prompt disappears in a instant.

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*)));
...
}

The logic is similar to an old answer of mine, in it a model is created that will store the information this prevents you from creating a QCompleter at every moment avoiding the problem the disappearance of the popup.

#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"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM