Qt不錯的學習網址:javascript
http://www.cnblogs.com/findumars/p/5529526.htmlhtml
----------------------------------------------------java
IE內核,qt調用js;qt寫com組件,html就能夠調用qtweb
能夠百度 QAxBindable 會搜索到比較有用的文章瀏覽器
http://blog.csdn.net/csxiaoshui/article/details/47333989安全
http://blog.csdn.net/csxiaoshui/article/details/48000885app
http://blog.csdn.net/csxiaoshui/article/details/50735018less
http://blog.csdn.net/jxd9955/article/details/30260725函數
ui->axWidget->setControl("Shell.Explorer");
ui->axWidget->setObjectName(QString::fromUtf8("WebBrowser"));
ui->axWidget->setFocusPolicy(Qt::StrongFocus);
//去邊框
ui->axWidget->setWindowFlags(Qt::FramelessWindowHint);
ui->axWidget->setStyleSheet("QGraphicsView{border:0px;}");
ui->axWidget->dynamicCall("Navigate(constQString&)",QString("file:///D:/proj/m5/m5/baidu_map_new.html"));
IWebBrowser2*webBrowser=0;
ui->axWidget->queryInterface(IID_IWebBrowser2,(void**)&webBrowser);
if(webBrowser)
{
VARIANT_BOOLresult;
HRESULTbusy=webBrowser->get_Busy(&result);
if(VARIANT_TRUE==result)
{
}
}
ui->axWidget->close();
ui->axWidget->show();
+++++++++++++++++++++++++++++++++++++++++++
調用js函數
voidMainWindow::SetLocation(std::wstringx,std::wstringy,std::wstringstr)
{
if(QString::fromStdWString(x).trimmed().isEmpty()||
QString::fromStdWString(y).trimmed().isEmpty())
{
QMessageBox::information(this,QString("NOTICE"),
#ifdefENGLISH_
QString("Targetaddressisempty!"));
#else
QString("目標地址爲空!"));
#endif//ENGLISH_
return;
}
QAxObject*document=ui->axWidget->querySubObject("Document");
IHTMLDocument2*doc2;
if(document!=NULL)
{
document->queryInterface(QUuid(IID_IHTMLDocument2),(void**)&doc2);
}
if(doc2)
{
IHTMLWindow2*win2=NULL;
if(doc2->get_parentWindow(&win2)==S_OK)
{
WCHARlocationInfo[MAX_PATH]={0};
wsprintf(locationInfo,L"setLocation(%s,%s,%s)",x.c_str(),y.c_str(),str.c_str());
BSTRs1=SysAllocString(locationInfo);
BSTRs2=SysAllocString(L"JavaScript");
VARIANTret;
if(win2!=NULL)
{
win2->execScript(s1,s2,&ret);
}
SysFreeString(s2);
SysFreeString(s1);
}
}
}
------------------------------------------------------------------------------post
QT5 與JS交互不錯的文章:
http://blog.csdn.net/d7185540/article/details/52896531
http://blog.csdn.net/sharetm/article/details/55260207
---------------------------------------------------------------------------
http://blog.csdn.net/liuhongwei123888/article/details/6162159
http://blog.csdn.net/styyzxjq2009/article/details/8364545
-----------------------------------------------------------------------------------
WebView與JS
這種用法不多見:
http://www.cnblogs.com/ziqiuqiandao/archive/2012/12/29/2838652.html
能夠獲取到html元素的值:
http://blog.csdn.net/liuhongwei123888/article/details/6137094
http://www.cnblogs.com/findumars/p/5529526.html能夠將QT的屬性值暴露給html文件。
大衆用法:
QString strFunc(tr("locateCity('南京', 11);"));
m_pWebView->page()->mainFrame()->evaluateJavaScript(strFunc);
幾個注意點:
QWebView爲什麼有些網頁顯示不了:
一、網頁是https協議的,使用SSL加密鏈接了。你的Qt庫集成了openssl模塊嗎?若是沒有,要-openssl開關重編QtNetwork庫。若是有,鏈接webView->page()->networkAccessManager()的sslErrors信號,調用QNetworkReply的ignoreSslErrors函數,而後把libeay32.dll和ssleay32.dll兩個文件和程序放到一塊兒。
二、把 qt-create中的 ssleay32.dll 和 libeay32.dll 複製到 qt sdk的 bin目錄下面
在學習Qt,作了個瀏覽器demo,沒搞懂對https是怎麼支持的?我開發的時候用的機器全部https網站都正常顯示,後來拿到另外一臺機器上,全是空白頁。網上有說是ssl握手產生錯誤的問題,我把代碼搞到後一臺機子上寫了發現仍是不行,根本沒收到sslerror的signal。用其它瀏覽器都是正常打開,不明白爲何?
是否是libeay32.dll和ssleay32.dll缺了?
是由於這2個dll,可是電腦裏是有的,其餘程序都能找到這個路徑就是我本身搞的不行,後來把openssl一塊兒打包了。
QWebView直接load能夠打開https網頁,網頁內的大多數的按鈕點擊卻無反應
NetworkAccessManager::createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData)裏能夠看到有請求返回,
但WebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type)卻收不到請求。
一、
有沒有試過調用QWebPager的setLinkDelegationPolicy函數,我以前有碰到過點擊連接不處理的問題,是由於沒有調用這個函數。
ui->webView->page()->setLinkDelegationPolicy(QWebPage::DelegateExternalLinks);
三、實在不行,參考方案:最終仍是QT整合MFC的CHtmlView來作
/* 開啓JavaScript支持 */ 好像不是必須的!!
QWebSettings *pWebSettings = m_pWebView->page()->settings();
pWebSettings->setAttribute(QWebSettings::JavascriptEnabled,true);
/* 創建信號與槽, 每次載入html時發送段信號 */ 必需要!!!
connect(m_pWebView->page()->mainFrame(),SIGNAL(javaScriptWindowObjectCleared()),
this,SLOT(addObjectToJs()));
Qt代碼裏先嚐試在javaScriptWindowObjectCleared信號對應的槽裏調用,結果失敗了:
connect(ui.webView->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
this, SLOT(populateJavaScriptWindowObject()));
...
void FormExtractor::populateJavaScriptWindowObject()
{
ui.webView->page()->mainFrame()->evaluateJavaScript("tryalert();");
}
是由於這個信號發出得太早了,頁面尚未徹底載入。須要在後面調用。最好是響應loadFinished(bool)信號:
connect(ui.webView->page()->mainFrame(), SIGNAL(loadFinished(bool)),
this, SLOT(callFunction()));
...
void FormExtractor::callFunction()
{
ui.webView->page()->mainFrame()->evaluateJavaScript("tryalert();");
}
該控件是用於在Qt中顯示網頁的控件,通常而言會將contextMenuPolicy屬性設置爲NoContextMenu隱藏系統爲其提供的默認右鍵菜單
<1>. 加載網頁:
1
2
3
|
//若是是本地網頁,必須使用file:///的前綴做爲網頁地址
|
<2>. Qt代碼中調用QWebview加載的網頁中的js函數:
1
2
3
4
5
6
7
8
9
10
|
//先做以下設置
ui->webViewCut->page()->setForwardUnsupportedContent(
true
);
ui->webViewCut->page()->settings()->setAttribute(QWebSettings::JavascriptEnabled,
true
);
ui->webViewCut->page()->settings()->setAttribute(QWebSettings::PluginsEnabled,
true
);
ui->webViewCut->page()->settings()->setAttribute(QWebSettings::JavaEnabled,
true
);
ui->webViewCut->page()->settings()->setAttribute(QWebSettings::AutoLoadImages,
true
);
//而後在QWebview的loadFinished槽函數中調用js,該槽函數表示網頁已經加載完畢
QString js = QString(
"alert(\'hello Qt!\')"
);
ui->webViewCut->page()->mainFrame()->evaluateJavaScript(js);
|
<3>. 在QWebview加載的html的js代碼中調用Qt的函數:
默認狀況下在QwebViewCut中的網頁裏面的js不能直接調用Qt中的相關功能,這涉及到安全性問題。要知足js中調用Qt的功能必須知足下面的條件:
在Qt中暴露一個對象給js,而後js就能夠在網頁中直接使用這個對象以及該對象的[特定]函數,要求是被暴露Qt對象必須繼承自QObject類,而且在js中調用這個暴露的對象的成員函數的定義是有要求的,該對象的知足下面的要求的成員函數均可以直接被js調用:
1.必須是該對象的公共函數,而且在函數聲明前面添加Q_INVOKABLE修飾,例如:
1
2
|
public
:
Q_INVOKABLE
int
TestQt();
|
2.若是該函數被聲明成一個public slot 也能夠不添加Q_INVOKABLE修飾:
1
2
|
public
slots:
void
TestQt();
|
我的認爲第一種方法更好,由於能夠設置返回值,而Qt的槽函數是沒有返回值的,都是返回void,只須要調用this->ui->webViewCut->page()->mainFrame()->addToJavaScriptWindowObject("QtObj", this);
就能夠將一個Qt對象,也就是這裏傳遞的this表明的對象,固然也能夠直接傳遞其餘對象指針,暴露給網頁中的javascript,網頁中的javascript在調用的時候能夠直接使用 QtObj 去引用咱們的Qt對象,以及經過QtObj去直接調用符合條件的Qt對象的成員函數。
那麼this->ui->webViewCut->page()->mainFrame()->addToJavaScriptWindowObject("QtObj", this);
代碼在何時執行呢? 推薦是在QWebFrame的信號javaScriptWindowObjectCleared
發出的時候執行,因此咱們能夠在當前UI界面類的構造函數中添加下面的代碼:
1
2
|
connect(ui->webViewCut->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
this
, SLOT(populateJavaScriptWindowObject()));
|
而後在處理javaScriptWindowObjectCleared()
信號的槽函數中實現上述暴露功能:
1
2
3
4
|
void
MainWindow::populateJavaScriptWindowObject()
{
ui->webViewCut->page()->mainFrame()->addToJavaScriptWindowObject(
"QtObj"
,
this
);
}
|
根據Qt文檔上對該信號的描述javaScriptWindowObjectCleared()
這個信號會在咱們調用QwebViewCut::load()
加載新的url以前就觸發,咱們在這個時候去處理這個信號,將咱們須要暴露的Qt對象暴露給即將載入的網頁
<4>. 將Qt的屬性暴露出去供js調用,使用以下方法:
1
|
Q_PROPERTY(
int
Qtvalue READ testValue WRITE setTestValue)
|
將上面的語句加入到類的聲明中,在private塊下面就能夠,最後不須要以分號結尾,例如:
1
2
|
private
:
Q_PROPERTY(
int
Qtvalue READ testValue WRITE setTestValue)
|
這一行的做用是將屬性 Qtvalue 註冊到Qt的元對象系統中,在js中能夠經過名字Qtvalue來訪問該屬性,但在js中訪問該屬性的時候假設Qt暴露給js的對象爲QtObj,那麼在js中能夠這樣訪問該屬性:
1
2
|
QtObj.Qtvalue = 10;
//設置該屬性的時候會調用void setTestValue(int)
alert(QtObj.Qtvalue)
//獲取該屬性的時候會調用 int testValue()
|
Q_PROPERTY(int Qtvalue READ testValue WRITE setTestValue)的結構以下:
1
2
|
Q_PROPERTY( 類型 屬性名 READ 返回屬性值的函數 WRITE 設置屬性值的函數 )
int
Qtvalue
int
testValue()
void
setTestValue(
int
)
|
也就是說在js中咱們能夠直接使用Qtvalue,當獲取Qtvalue的值的時候會自動調用暴露對象的 int testValue() 函數 ,Qt規定其返回值必須與Q_PROPERTY語句中指定的類型相同,而且必須沒有參數。當咱們爲Qtvalue設置值的時候會調用暴露對象的void setTestValue(int)
函數,該函數必須有一個int類型的參數(類型也必須與前面Q_PROPERTY語句中指定的類型相同),而且不能有返回值。
通過實驗int testValue()
與void setTestValue(int)
函數的聲明在private區域也能夠,好像無所謂。其實這兩個函數的名字是能夠隨意定的,對js暴露的屬性名是Qtvalue,當訪問Qtvalue屬性的時候,會自動調用Q_PROPERTY聲明中READ後面指定的函數去獲取值,而且調用WRITE後面指定的函數去設置值,而不在意這兩個函數的名字。
另外這兩個函數獲取的值或者設置的值從哪裏得來呢,咱們能夠在Qt對象中定義一個私有變量來保存這個值,而這個私有變量的名字是無所謂的,甚至若是須要的話,咱們也沒必要保存這個值,直接在函數testValue裏面返回一個常量值,也就是說是否應該定義一個私有變量來保存Qtvalue相關聯的屬性值,這個也不是必須的。
更多Qt QWidget與js的交互能夠在Qt文檔中搜索 The Qt WebKit Bridge
關鍵字,其實Q_PROPERTY並非專用於暴露屬性給js的,Q_PROPERTY是Qt元對象系統的一部分。
<5>. 若是在QWebview加載的網頁中有Flex應用程序,而且Qt中調用該QWebview加載的網頁中的js函數中須要調用flex程序暴露給js的接口,那麼還須要做以下設置:
在"%appdata%\Macromedia\Flash Player\#Security\FlashPlayerTrust\"
路徑下新建xxx.cfg文件,將當前flex應用程序所在位置(也就是swf文件所在的目錄)填寫到該文件中便可,該xxx.cfg的名字是無所謂的,隨便什麼名字,在xxx.cfg文件中指定的目錄路徑中的swf文件的運行是被信任的。xxx.cfg文件中能夠指定多個目錄,每行一個。實際上%appdata%\Macromedia\Flash Player\#Security\FlashPlayerTrust\
路徑下也能夠有多個文件名不一樣的cfg文件。xxx.cfg文件中指定的目錄實際上能夠直接指定爲根目錄,例如swf文件的路徑是F:/xxx/yyy/zzz/test.swf
,那麼咱們新建的xxx.cfg中的內容的第一行能夠直接指定爲F:/便可。
其實FlexBuilder在創建項目的時候,其生成的swf所在的目錄都被添加到了%appdata%\Macromedia\Flash Player\#Security\FlashPlayerTrust\
下面的flashbuilder.cfg中了,因此使用FlexBuilder調試項目的時候,運行的swf都是被信任的。
js調用QT時,傳遞參數類型:
註冊:
m_pWebView->page()->mainFrame()->addToJavaScriptWindowObject("m5_js",this);
js調用qt的函數
void m5_js::setInfor(const QString a)
{
ui.btadd->setText(a);
}
js函數:
function attribute() {
var p = marker.getPosition();
var ll = p.lng.toString();
m5_js.setInfor(ll)
//m5_js.setInfor(p.lng.toString())
//獲取marker的位置
alert("marker的位置是" + p.lng + "," + p.lat);
}
Qt代碼裏先嚐試在javaScriptWindowObjectCleared信號對應的槽裏調用,結果失敗了:
connect(ui.webView->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
this, SLOT(populateJavaScriptWindowObject()));
...
void FormExtractor::populateJavaScriptWindowObject()
{
ui.webView->page()->mainFrame()->evaluateJavaScript("tryalert();");
}
是由於這個信號發出得太早了,頁面尚未徹底載入。須要在後面調用。最好是響應loadFinished(bool)信號:
connect(ui.webView->page()->mainFrame(), SIGNAL(loadFinished(bool)),
this, SLOT(callFunction()));
...
void FormExtractor::callFunction()
{
ui.webView->page()->mainFrame()->evaluateJavaScript("tryalert();");
}