目录
背景
最近迷上了WEB相关的代码,上个月初步分析了HTTP协议,能用telnet构造HTTP封包直接和WEB服务器通信,昨天晚上看到了Qt5.5.1版本里面有一个例子Form Extractor Example,这个例子简直刷新了我对Qt的认识!
原来在官方认为:
不仅仅可以用widges做界面,Qt后端数据处理;
QML做界面,Qt后端处理。
竟然还能用HTML做界面,Qt后端处理,在此把Form Extractor Example这个实例给分析一下!
解析官方例子
这里先放一个截图:
首先来看看文件的存储结构:
进formextractor.ui看看
发现这是一个QWidget界面,而在程序跑起来后,竟然有菜单栏!
这里,看看mainwindw.h,发现这个是QMainWindow,再看下mainwindow.cpp发现他构造了一个界面,然后把QWidget界面,放到了setCentralWidget里面!
这里就有了一个疑惑,为什么官方不直接把界面放到QMainwindw里面,而是先放到QWidget,再放进去呢?
这葫芦里到底是卖的什么药?????
因为这个例子,官方没有给其他说明,所以,在此我就猜测下!
估计是为了方便管理把,主控界面放到主控界面的UI里面,程序大体框架,放到大体框架里面,估计就是这样了把!
下面来看下:
formextractor.cpp代码:
#include "formextractor.h"
#include <QWebElement>
FormExtractor::FormExtractor(QWidget *parent, Qt::WindowFlags flags)
: QWidget(parent, flags)
{
ui.setupUi(this);
ui.webView->setUrl(QUrl("qrc:/form.html"));
connect(ui.webView->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
this, SLOT(populateJavaScriptWindowObject()));
resize(300, 300);
}
FormExtractor::~FormExtractor()
{
}
void FormExtractor::submit()
{
QWebFrame *frame = ui.webView->page()->mainFrame();
QWebElement firstName = frame->findFirstElement("#firstname");
QWebElement lastName = frame->findFirstElement("#lastname");
QWebElement maleGender = frame->findFirstElement("#genderMale");
QWebElement femaleGender = frame->findFirstElement("#genderFemale");
QWebElement updates = frame->findFirstElement("#updates");
ui.firstNameEdit->setText(firstName.evaluateJavaScript("this.value").toString());
ui.lastNameEdit->setText(lastName.evaluateJavaScript("this.value").toString());
if (maleGender.evaluateJavaScript("this.checked").toBool())
ui.genderEdit->setText(maleGender.evaluateJavaScript("this.value").toString());
else if (femaleGender.evaluateJavaScript("this.checked").toBool())
ui.genderEdit->setText(femaleGender.evaluateJavaScript("this.value").toString());
if (updates.evaluateJavaScript("this.checked").toBool())
ui.updatesEdit->setText("Yes");
else
ui.updatesEdit->setText("No");
}
void FormExtractor::populateJavaScriptWindowObject()
{
ui.webView->page()->mainFrame()->addToJavaScriptWindowObject("formExtractor", this);
}
从这里我们可以知道:
当页面声明了JavaScript后,就会发出信号,嗲用populxxxxxxx这个函数!
这里有2个疑惑,一个是:
点击了界面的Submit后,才会进入populxxxxxxx,并不是加载页面后,就进入这个函数,这里估计可以知道,当点击了Submit后,才有JavaScript的声明,
下面来看下html代码:
form.html
<html><body>
<h1>
The Green People Book Club
</h1>
<p>
Welcome to The Green People Book Club. Please register to obtain a membership with us.
</p>
<form onsubmit="formExtractor.submit()">
<table>
<tbody><tr>
<td>
First name:
</td>
<td>
<input type="text" id="firstname">
</td>
</tr>
<tr>
<td>
Last name:
</td>
<td>
<input type="text" id="lastname">
</td>
</tr>
<tr>
<td>
Gender:
</td>
<td>
<input type="radio" name="gender" id="genderMale" value="Male"> Male
<input type="radio" name="gender" id="genderFemale" value="Female"> Female
</td>
</tr>
<tr>
<td colspan="2">
<input type="checkbox" id="updates" value="receive">
Check here if you would like to receive regular updates from us:
</td>
</tr>
</tbody></table>
<input type="submit" value="Submit">
</form>
</body></html>
这里也没明显的看到JavaScript代码!表单里面也没有说什么Post,Get方法啥的
我估计就是这个原因把:
最后看一下这个函数:
void FormExtractor::submit()
{
QWebFrame *frame = ui.webView->page()->mainFrame();
QWebElement firstName = frame->findFirstElement("#firstname");
QWebElement lastName = frame->findFirstElement("#lastname");
QWebElement maleGender = frame->findFirstElement("#genderMale");
QWebElement femaleGender = frame->findFirstElement("#genderFemale");
QWebElement updates = frame->findFirstElement("#updates");
ui.firstNameEdit->setText(firstName.evaluateJavaScript("this.value").toString());
ui.lastNameEdit->setText(lastName.evaluateJavaScript("this.value").toString());
if (maleGender.evaluateJavaScript("this.checked").toBool())
ui.genderEdit->setText(maleGender.evaluateJavaScript("this.value").toString());
else if (femaleGender.evaluateJavaScript("this.checked").toBool())
ui.genderEdit->setText(femaleGender.evaluateJavaScript("this.value").toString());
if (updates.evaluateJavaScript("this.checked").toBool())
ui.updatesEdit->setText("Yes");
else
ui.updatesEdit->setText("No");
}
从中,可以知道,通过QWebElement可以直接获取html中填充的数据!
简直是神器啊!