簡體   English   中英

QCompleter在NetworkRequest完成后無法正常工作

[英]QCompleter doesn't work properly with NetworkRequest finished

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM