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>
效果图:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGF2aWRzdTMz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
版权声明:本文博客原创文章,博客,未经同意,不得转载。
QtNetwork说明(两)使用QT实现360的ctrl+ctrl特征的更多相关文章
- 【技术贴】删除360快捷搜索 ctrl+ctrl
恶心的功能,这么变态!如何删除360快捷键ctrl,桌面跳出360搜索怎么办?360 ctrl 删除 卸载方法: 桌面右下角,在360图标上右键点击设置,进入设置中心. 把 [开启快捷搜索功能,双击C ...
- Qt实现360安全卫士10.0界面(编译时出现的一些问题)
http://www.qtcn.org/bbs/read-htm-tid-57817.html 源码下载:https://git.oschina.net/zhjun5337/Qt360-10.0 或 ...
- PyQt(Python+Qt)学习随笔:QCommandLinkButton的特征及用途
CommandLinkButton是Windows Vista引入的新控件,,它的预期用途与单选按钮类似,用于在一组互斥选项之间进行选择.命令链接按钮不应单独使用,而应作为向导和对话框中单选按钮的替代 ...
- 两个常见Qt编译错误的解决
作者:朱金灿 来源:http://blog.csdn.net/clever101 如果在电脑上安装了两个Qt版本,在编译一个工程时有可能出现如下的编译错误: ERROR: failed to refr ...
- xmake新增对Qt编译环境支持
在最新的xmake v2.2.1版本中,新增了对Qt SDK环境的支持,我们完全可以脱离Qt Creater进行Qt应用程序的开发,甚至配合vscode/idea等编辑器+xmake插件(xmake- ...
- QT UDP聊天小程序
利用QT的UDP技术,实现两个QT程序之间的聊天程序. #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include < ...
- Qt opencv程序运行异常
搭建了两次qt opencv vs ,经常出现程序运行异常.找了几个原因如下: 1.opencv的路径未配置或配置有误. 2.qt中pro文件包含不正确. 3.测试opencv程序不正确.如视频或图片 ...
- 记录下 QT Linux 静态编译遇到的坑
Qt下静态编译Qt,根据我的经验,如果按照Windows下那种直接拿官方sdk安装之后的文件来编译是行不通的,需要直接下载Qt的source包,目前诺基亚的源码叫做qt-everywhere-open ...
- Qt入门(13)——Qt的调用退出
如果我们创建了一个窗口,接下来使这个应用程序在用户让它退出的时候退出. #include <qfont.h>因为这个程序使用了QFont,所以它需要包含qfont.h.Qt的字体提取和X中 ...
随机推荐
- 【IOS 开发】Object-C 入门 Xcode 环境具体解释
作者 : 韩曙亮 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/38424965 一. Xcode 环境安装 与 project ...
- 使用批处理文件命令行方式快速启动和停止IIS、SqlServer
原文:使用批处理文件命令行方式快速启动和停止IIS.SqlServer 虽然现在内存便宜了,但是自己还是嫌自己的512M内存太小,没办法,后台运行的东西太多了,有很多都是有用的没法关闭的.IIS和SQ ...
- MVC — 第 6 天
7 天玩转 ASP.NET MVC — 第 6 天 目录 第 1 天 第 2 天 第 3 天 第 4 天 第 5 天 第 6 天 第 7 天 0. 前言 欢迎来到第六天的 MVC 系列学习中.希望 ...
- [Cocos2d-x]Cocos2d-x 3.2 学习笔记
获取屏幕大小(Visible) Size visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Direc ...
- 【Struts2学习笔记(2)】Action默认值和配置Action于result各种转发类型
一.Action缺省配置值 <span style="font-size:18px;"><package name="itcast" name ...
- Javascript DOM编程艺术
Chapter 0 为什么读这本书?作为js入门书,补基础,由于本书代码demo较简单,并没有贴代码,只记录一些自己要注意的知识点以及代码脚本 Chapter 1: javascript简史 DOM全 ...
- 采用Duplicate target database在线恢复秩序oracle datagard图书馆设备
线上oracle datagard备库由于断电以及误删除从库的归档日志文件,所以导致,备库主库数据不一致,备库须要紧急恢复.以下是大概恢复过程 1,从主库上面备份控制文件[oracle@localho ...
- 数独 (dfs)
自从2006年3月10日至11日的首届数独世界锦标赛以后,数独这项游戏越来越受到人们的喜爱和重视.据说,在2008北京奥运会上,会将数独列为一个单独的项目进行比赛,冠军将有可能获得的一份巨大的奖品—— ...
- 《python源代码分析》笔记 pythonVM一般表达式
本文senlie原版的.转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.字节码指令 LOAD_CONST:从consts表中读取序号为i的元素并压入到执行时栈中 ...
- crawler_爬虫_反爬虫策略
关于反爬虫和恶意攻击的一些策略和思路 有时网站经常受到恶意spider攻击,疯狂抓取网站内容,对网站性能有较大影响. 下面我说说一些反恶意spider和spam的策略和思路. 1. 通过日志分析来 ...