先看文档:
This function is called whenever WebKit requeststo navigate frame to the resource specified by request by means of the specified navigationtype type.
If frame is a null pointer then navigation to anew window is requested. If the request is accepted createWindow() will be called.
The default implementation interprets thepage's linkDelegationPolicy and emits linkClicked accordingly orreturns true to let QWebPage handlethe navigation itself.
说的比较简单。
这个函数对资源请求提供了一些基本的处理。但是对用户点击链接没有进行处理,所以对用户点击链接这样的操作必须专门去处理,否则点击链接会没有反应,不能打开相应的页面。
处理用户点击链接比较简单的方法是设置setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
将自己的处理槽连接到linkClicked信号。就可以工作了。
但是因为linkClicked信号只有url参数,要想处理细节,比如,是在新标签或新窗口中还是在原窗口中打开链接等,还必须从acceptNavigationRequest入手。
在这里,你还可以截获request,甚至将其重新组装后再发送出去(首先声明我没有用过,没试过,只是理论上可以这样做。因为我一般都是在
virtual QNetworkReply * QNetworkAccessManager::createRequest(QNetworkAccessManager::Operationop,constQNetworkRequest&request,QIODevice*outgoingData)
但是要注意,这段代码只是说明了用法,并不实用,否则会有问题。
因为当用户点击链接,此函数发送了openLink(request.url())或loadLink(request.url())信号,然后又执行了父类的QWebPage::acceptNavigationRequest(frame, request, type)。
如果你对应于前两个信号的槽又执行了QWebView::load()(应该是都会执行,除非你并不想将这一请求发送出去),那么又会再次进入此函数,此次会再次直接执行父类的QWebPage::acceptNavigationRequest(frame, request, type)。
会出现什么情况文档上没写,我也没去看源代码,总之这样不妥。我试过,会造成程序莫名其妙的随机崩溃。
这样可以避免两次执行父类的QWebPage::acceptNavigationRequest(frame,request, type)。
bool QWebPage::acceptNavigationRequest ( QWebFrame * frame, constQNetworkRequest & request, NavigationType type ) [virtualprotected]
This function is called whenever WebKit requeststo navigate frame to the resource specified by request by means of the specified navigationtype type.
If frame is a null pointer then navigation to anew window is requested. If the request is accepted createWindow() will be called.
The default implementation interprets thepage's linkDelegationPolicy and emits linkClicked accordingly orreturns true to let QWebPage handlethe navigation itself.
说的比较简单。
这个函数对资源请求提供了一些基本的处理。但是对用户点击链接没有进行处理,所以对用户点击链接这样的操作必须专门去处理,否则点击链接会没有反应,不能打开相应的页面。
处理用户点击链接比较简单的方法是设置setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
将自己的处理槽连接到linkClicked信号。就可以工作了。
但是因为linkClicked信号只有url参数,要想处理细节,比如,是在新标签或新窗口中还是在原窗口中打开链接等,还必须从acceptNavigationRequest入手。
在这里,你还可以截获request,甚至将其重新组装后再发送出去(首先声明我没有用过,没试过,只是理论上可以这样做。因为我一般都是在
virtual QNetworkReply * QNetworkAccessManager::createRequest(QNetworkAccessManager::Operationop,constQNetworkRequest&request,QIODevice*outgoingData)
中进行处理,方便连Cookies都处理了。)
- bool webPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest&request, NavigationType type)
- {
- if(type==0){//如果是用户点击
- if(frame!=mainFrame()){ //如果不是在本窗口的连接
- emit openLink(request.url());//发送打开新连接信号
- }else{
- emit loadLink(request.url());//发送点击连接信号
- }
- }
- return QWebPage::acceptNavigationRequest(frame, request, type);
- }
因为当用户点击链接,此函数发送了openLink(request.url())或loadLink(request.url())信号,然后又执行了父类的QWebPage::acceptNavigationRequest(frame, request, type)。
如果你对应于前两个信号的槽又执行了QWebView::load()(应该是都会执行,除非你并不想将这一请求发送出去),那么又会再次进入此函数,此次会再次直接执行父类的QWebPage::acceptNavigationRequest(frame, request, type)。
会出现什么情况文档上没写,我也没去看源代码,总之这样不妥。我试过,会造成程序莫名其妙的随机崩溃。
实用的写法应该是这样的:
- bool webPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest&request, NavigationType type)
- {
- if(type==0){//如果是用户点击
- if(frame!=mainFrame()){ //如果不是在本窗口的连接
- emit openLink(request.url());//发送打开新连接信号
- }else{
- emit loadLink(request.url());//发送点击连接信号
- }
- return false;
- }
- return QWebPage::acceptNavigationRequest(frame, request, type);
- }
这样可以避免两次执行父类的QWebPage::acceptNavigationRequest(frame,request, type)。
总之,你自己已完整地处理过了,就不要再交给父类的方法去处理了。你没有处理过的才交给父类去按默认方式去处理。