• QtNetwork说明(两)使用QT实现360的ctrl+ctrl特征


    头文字说明:

    <span style="font-size:18px;">#ifndef GOOGLESUGGEST_H
    #define GOOGLESUGGEST_H
    
    #include <QtGui>
    #include <QtNetwork>
    #include <QObject>
    
    QT_BEGIN_NAMESPACE
    class QLineEdit;
    class QNetworkReply;
    class QTimer;
    class QTreeWidget;
    QT_END_NAMESPACE
    
    //! [1]
    class GSuggestCompletion : public QObject
    {
        Q_OBJECT
    
    public:
        GSuggestCompletion(QLineEdit *parent = 0);
        ~GSuggestCompletion();
        bool eventFilter(QObject *obj, QEvent *ev);
        void showCompletion(const QStringList &choices, const QStringList &hits);
    
    public slots:
    
        void doneCompletion();
        void preventSuggest();
        void autoSuggest();
        void handleNetworkData(QNetworkReply *networkReply);
    
    private:
        QLineEdit *editor;
        QTreeWidget *popup;
        QTimer *timer;
        QNetworkAccessManager networkManager;
    };
    //! [1]
    #endif // GOOGLESUGGEST_H</span>

    源码:

    <span style="font-size:18px;">//made by davidsu33
    //2014-10-10
    //QT的googlesuggest的改造版本号
    //将其改造为360的搜索
    //使用工具QNetwork模块, boost的属性树以及typeof
    
    
    //! [1]
    #include "googlesuggest.h"
    #include <boost/property_tree/ptree.hpp>
    #include <boost/property_tree/json_parser.hpp>
    #include <boost/typeof/typeof.hpp>
    #include <boost/foreach.hpp>
    
    #include <sstream>
    //#include <iosfwd>
    #include <QRegExp>
    
    //常规浏览器查找 URL http://sug.so.360.cn/suggest?callback=suggest_so&encodein=utf-8&encodeout=utf-8&format=json&fields=word,obdata&word=m
    #define GSUGGEST_URL "http://sug.so.360.cn/suggest?callback=suggest_so&encodein=utf-8&encodeout=utf-8&format=json&fields=word,obdata&word=%1"
    //#define GSUGGEST_URL "http://google.com/complete/search?output=toolbar&q=%1"
    //! [1]
    
    //! [2]
    GSuggestCompletion::GSuggestCompletion(QLineEdit *parent): QObject(parent), editor(parent)
    {
        popup = new QTreeWidget;
        popup->setWindowFlags(Qt::Popup);
        popup->setFocusPolicy(Qt::NoFocus);
        popup->setFocusProxy(parent);
        popup->setMouseTracking(true);
    
        popup->setColumnCount(2);
        popup->setUniformRowHeights(true);
        popup->setRootIsDecorated(false);
        popup->setEditTriggers(QTreeWidget::NoEditTriggers);
        popup->setSelectionBehavior(QTreeWidget::SelectRows);
        popup->setFrameStyle(QFrame::Box | QFrame::Plain);
        popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        popup->header()->hide();
    
        popup->installEventFilter(this);
    
        connect(popup, SIGNAL(itemClicked(QTreeWidgetItem*,int)),
                SLOT(doneCompletion()));
    
        timer = new QTimer(this);
        timer->setSingleShot(true);
        timer->setInterval(500);
        connect(timer, SIGNAL(timeout()), SLOT(autoSuggest()));
        connect(editor, SIGNAL(textEdited(QString)), timer, SLOT(start()));
    
        connect(&networkManager, SIGNAL(finished(QNetworkReply*)),
                this, SLOT(handleNetworkData(QNetworkReply*)));
    
    }
    //! [2]
    
    //! [3]
    GSuggestCompletion::~GSuggestCompletion()
    {
        delete popup;
    }
    //! [3]
    
    //! [4]
    bool GSuggestCompletion::eventFilter(QObject *obj, QEvent *ev)
    {
        if (obj != popup)
            return false;
    
        if (ev->type() == QEvent::MouseButtonPress) {
            popup->hide();
            editor->setFocus();
            return true;
        }
    
        if (ev->type() == QEvent::KeyPress) {
    
            bool consumed = false;
            int key = static_cast<QKeyEvent*>(ev)->key();
            switch (key) {
            case Qt::Key_Enter:
            case Qt::Key_Return:
                doneCompletion();
                consumed = true;
    
            case Qt::Key_Escape:
                editor->setFocus();
                popup->hide();
                consumed = true;
    
            case Qt::Key_Up:
            case Qt::Key_Down:
            case Qt::Key_Home:
            case Qt::Key_End:
            case Qt::Key_PageUp:
            case Qt::Key_PageDown:
                break;
    
            default:
                editor->setFocus();
                editor->event(ev);
                popup->hide();
                break;
            }
    
            return consumed;
        }
    
        return false;
    }
    //! [4]
    
    //! [5]
    void GSuggestCompletion::showCompletion(const QStringList &choices, const QStringList &hits)
    {
    
        if (choices.isEmpty() || choices.count() != hits.count())
            return;
    
        const QPalette &pal = editor->palette();
        QColor color = pal.color(QPalette::Disabled, QPalette::WindowText);
    
        popup->setUpdatesEnabled(false);
        popup->clear();
        for (int i = 0; i < choices.count(); ++i) {
            QTreeWidgetItem * item;
            item = new QTreeWidgetItem(popup);
            item->setText(0, choices[i]);
            item->setText(1, hits[i]);
            item->setTextAlignment(1, Qt::AlignRight);
            item->setTextColor(1, color);
        }
        popup->setCurrentItem(popup->topLevelItem(0));
        popup->resizeColumnToContents(0);
        popup->resizeColumnToContents(1);
        popup->adjustSize();
        popup->setUpdatesEnabled(true);
    
        int h = popup->sizeHintForRow(0) * qMin(7, choices.count()) + 3;
        popup->resize(popup->width(), h);
    
        popup->move(editor->mapToGlobal(QPoint(0, editor->height())));
        popup->setFocus();
        popup->show();
    }
    //! [5]
    
    //! [6]
    void GSuggestCompletion::doneCompletion()
    {
        timer->stop();
        popup->hide();
        editor->setFocus();
        QTreeWidgetItem *item = popup->currentItem();
        if (item) {
            editor->setText(item->text(0));
            QMetaObject::invokeMethod(editor, "returnPressed");
        }
    }
    //! [6]
    
    //! [7]
    void GSuggestCompletion::autoSuggest()
    {
    	//UTF-8的编码
        QString str = editor->text();
        QString url = QString(GSUGGEST_URL).arg(str);
    	QUrl suggesturl(url);
    	//suggesturl.setEncodedUrl(url.toAscii());
    	//suggesturl.setHost("http://sug.so.360.cn/");
    
    	QString strPath = suggesturl.encodedPath();
    	QString strQuery = suggesturl.encodedQuery();
    
    	QNetworkRequest req;
    	req.setUrl(suggesturl);
    	//req.setRawHeader("Accept", "application/javascript, */*;q=0.8");
    	//req.setRawHeader("Referer", "http://www.so.com/");
    	//req.setRawHeader("Accept-Language", "zh-CN");
    	//req.setRawHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)");
    	//req.setRawHeader("Accept-Encoding", "gzip, deflate");
    	//req.setRawHeader("Host", "sug.so.360.cn");
    	//req.setRawHeader("Cookie","__huid=10X%2FLQOe%2B%2FDQlxBkH8JUO9HzQNDDQ5t9e2HqTqhs2HUlw%3D; __guid=132730903.1687894815517624600.1412906141457.4387");
        networkManager.get(req);
    
    	//Accept: application/javascript, */*;q=0.8
    	//Referer: http://www.so.com/
    	//Accept-Language: zh-CN
    	//User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
    	//Accept-Encoding: gzip, deflate
    }
    //! [7]
    
    //! [8]
    void GSuggestCompletion::preventSuggest()
    {
        timer->stop();
    }
    //! [8]
    
    //! [9]
    void GSuggestCompletion::handleNetworkData(QNetworkReply *networkReply)
    {
        QUrl url = networkReply->url();
    	QNetworkReply::NetworkError nerror = networkReply->error();
        if (!networkReply->error()) {
    		//解析jason数据,UTF-8编码	
    
            QStringList choices;
            QStringList hits;
    		
    
            QByteArray response(networkReply->readAll());
    		QString strResponse(response);
    		QString strResponse2 = QString::fromUtf8(response.data(), response.size());
    		QString strResponse3 = QString::fromAscii(response.data(), response.size());
    		qDebug()<<strResponse;
    		
    		QRegExp exp("\s*suggest_so\((.+)\);");
    		int pos = exp.indexIn(strResponse);
    		 QStringList capTexts = exp.capturedTexts();
    		assert(capTexts[1].size() > 0);
    
    		std::wstring wdata = strResponse.toStdWString();
    		qDebug()<<wdata.c_str();
    
    		qDebug()<<capTexts[1];
    		wdata = capTexts[1].toStdWString();
    
    		//处理成json数据的标准格式
    
    		std::wstringstream wstream(wdata);
    
    		boost::property_tree::wptree pt;
    		try
    		{
    <strong><span style="color:#ff0000;">			//之前这里崩溃报错 expected array。是由于输入的数据不是标准的json格式
    			//须要将其规则标准化
    			boost::property_tree::read_json<boost::property_tree::wptree>(wstream, pt);</span></strong>
    		}
    		catch (const boost::property_tree::json_parser_error& e )
    		{
    			qDebug()<<"what 's "<<e.what();
    			qDebug()<<"message:"<<e.message().c_str();
    			assert(false);
    		}
    		
    		QString aline, alinesecond, aword;
    		std::wstring query_object = pt.get<std::wstring>(L"query");
    
    		//BOOST_FOREACH(boost::property_tree::wptree::value_type &child, pt.get_child(L"result"))
    		//{
    
    		//}
    
    		BOOST_AUTO(child, pt.get_child(L"result"));
    		for (BOOST_AUTO(it, child.begin()); it != child.end(); ++it)
    		{
    <strong><span style="color:#ff0000;">			//get_child的键值对。其second仍然是一颗树
    			//aline = QString::fromStdWString(it->first.data());
    			//alinesecond = QString::fromStdWString(it->second.data());//ERROR
    			//aword = QString::fromStdWString(it->get<std::wstring>(L"word"));//ERROR
    
    			 boost::property_tree::wptree& childparse = it->second; 
    			 aword = QString::fromStdWString(childparse.get<std::wstring>(L"word"));
    			qDebug()<<aword;
    			choices<<aword;
    			hits<<QString::null;</span></strong>
    		}
    
            //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();
            //        }
            //    if (xml.tokenType() == QXmlStreamReader::StartElement)
            //        if (xml.name() == "num_queries") {
            //            QStringRef str = xml.attributes().value("int");
            //            hits << str.toString();
            //        }
            //}
    
            showCompletion(choices, hits);
        }
    
        networkReply->deleteLater();
    }
    //! [9]
    </span>
    效果图:



    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    cron生成
    sp_addlinkedserver,Synonym
    上海城市坐标
    评分插件 jquery.raty.js
    ORA-12514: TNS:listener does not currently know of service requested in connect
    ORA-01034: ORACLE not available ORA-27101: shared memory realm does not exist
    工厂模式
    单例模式
    Qt中的Q_OBJECT作用, 以及信号槽
    DDLog-不同颜色打印信息
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4616931.html
Copyright © 2020-2023  润新知