1. 問題描述
Qt專案打包交付后在一臺客戶機上面出現了打開界面就停止運行

由于在客戶機上沒有代碼除錯環境,不能聯網,不能重裝系統,就直接用該客戶機器上的vs2010對exe界面程式進行除錯
發現中斷行程中提示“下面的框架可能不正確或缺失,沒有為ntdll.dll加載符號”,再看下面的行程,有對Qt5WebEngineWidgets.dll,Qt5WebEngineCore.dll,Qt5WebChannel.dll的提示,這三個動態庫是專案使用了QWebEngineView控制元件才加進去的,是通過間接呼叫QtWebEngineProcess.exe來進行,然后,在打包的軟體的路徑下雙擊QtWebEngineProcess.exe發現也是會停止運行,在別的客戶機上雙擊這個exe是一閃而過,也就是該機器系統不支持這個庫,當前qt版本是5.14.2,后來又測驗了以下方法都沒有在該2機器上解決這個問題:
- 用qt msvc2017_32編譯軟體,在該機器上同樣的問題
- 替換Qt版本為5.14.0,在該機器上同樣的問題
- 替換其他同型號客戶機上可用的ntdll.dll等系統庫(不要輕易嘗試,可能會讓系統奔潰),該機器上測驗失敗
- Qt bug串列網發現說是可能是機器顯卡和顯卡驅動不匹配導致,然后重裝該機器顯卡驅動(聯想機器,在官網下載的專用顯卡驅動,沒有測驗其他通用顯卡驅動),還是沒有解決
2. 問題定位
由于該客戶機對解決問題的局限比較大,經過各種方法測驗,后在工程中去掉QWebEngineView控制元件的使用,重新編譯發現在該機器可以正常運行,但是少了用到QWebEngineView的部分功能
將問題定位為QWebEngineView(QtWebEngineProcess.exe)控制元件對部分舊機器或系統兼容性不好
3. 問題解決方案(選用Qt別的web控制元件)
在不同QT版本中使用的類和方法不同:
-
Qt4中使用webkit模塊;
-
Qt5 ~Qt5.5使用webkitwidgets模塊;
-
Qt5.6以上MSVC版本使用webenginewidgets模塊,Qt5.6以后,移除了QtWebkit這個組件
-
Qt5.6以后的mingw版本,不能使用QtWebEngine,只能使用QAxWidget控制元件
專案當前使用的是第三種方式出現問題,排除第三種方式,第一種是Qt4也排除掉,可選第二種或者第四種,這里選擇用QAxWidget的方案,不用降低Qt版本,
先參考下幾種方式的使用方法:
1)Qt4版本
Qt4使用webkit模塊,
1. 創建一個Widget類的QT工程,在pro工程檔案中添加 webkit network :
QT += core gui webkit network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = web
TEMPLATE = app
SOURCES += main.cpp\
widget.cpp
HEADERS += widget.h
FORMS += widget.ui
2. 編輯widget.h檔案,在Widget類中添加一個指標成員,該指標指向一個QWebView類:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtWebKit/QWebView>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
QWebView *view;
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
3. 修改widget.cpp,實作下面兩個成員函式
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
Widget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
view = new QWebView(this);
view->load(QUrl("http://www.baidu.com"));
view.showMaximized();
}
Widget::~Widget()
{
delete view;
delete ui;
}
2) Qt5 ~ Qt5.5版本
Qt5版本之后,將QWebView、QWebFrame、QWebPage、QWebInspector等類被單獨移到了webkitwidgets模塊,不再在QtWebKit模塊中,因此需使用webkitwidgets模塊,
和Qt4的區別僅在于pro檔案中添加的模塊不同和widget.h檔案中包含的頭檔案不同,
QT += core gui webkitwidgets network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtWebKitWidgets/QWebView>
3) Qt5.6及以上版本
Qt5.5.1是最后一個支持webkitwidgets的版本,在5.6版本以及之后的版本,Qt將webkitwidgets模塊移除,并用一個新的模塊webenginewidgets代替,
1. 創建一個Widget類的QT工程,在pro工程檔案中添加 webenginewidgets:
QT += core gui webenginewidgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = web
TEMPLATE = app
SOURCES += \
main.cpp \
widget.cpp
HEADERS += \
widget.h
FORMS += \
widget.ui
RESOURCES +=
2. 編輯widget.h檔案,包含QWebEngineView頭檔案,并在Widget類中添加一個指標成員,該指標指向一個QWebEngineView類:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QWebEngineView>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
QWebEngineView *view;
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
3. 修改widget.cpp,實作下面兩個成員函式
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
Widget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
view = new QWebEngineView(this);
view->load(QUrl(QStringLiteral("http://www.baidu.com")));
view.showMaximized();
}
Widget::~Widget()
{
delete view;
delete ui;
}
4)Qt5.6以后的mingw版本,使用 QAxWidget 顯示網頁
使用QAxWidget前需要注意兩點:
1.QAxContainer.lib,QAxServer.lib庫不可缺,
2.開發機本身具有相應的IE游覽器(注冊表檔案一致)
第①種 QAxContainer.lib,QAxServer.lib參考方式:

關于注冊表檔案:

QAxWidget *flash = new QAxWidget(0, 0); //QAxWidget使用的是ActiveX插件
flash->resize(600, 400); //設定該控制元件的初始大小
flash->setControl(QString::fromUtf8("{8856F961-340A-11D0-A96B-00C04FD705A2}"));//注冊組件ID
flash->setProperty("DisplayAlerts", false);//不顯示警告資訊
flash->setProperty("DisplayScrollBars", true);//不顯示滾動條
QString webstr = QString("www.baidu.com");//設定要打開的網頁
flash->dynamicCall("Navigate(const QString&)", webstr);//顯示網頁
flash->show();
第②種 在pro檔案里加入一句:
QT += axcontainer
顯示網頁的代碼如下:
this->ui->axWidget->setControl(QString::fromUtf8("{8856F961-340A-11D0-A96B-00C04FD705A2}"));//注冊組件ID
this->ui->axWidget->setProperty("DisplayAlerts",false);//不顯示警告資訊
this->ui->axWidget->setProperty("DisplayScrollBars",true);//不顯示滾動條
QString webstr=QString("github.com");//設定要打開的網頁
this->ui->axWidget->dynamicCall("Navigate(const QString&)",webstr);//顯示網頁
webWidget->dynamicCall("Navigate(const QString&)", "file:///"+QCoreApplication::applicationDirPath()+"/drawChart/report.html"); //加載本地檔案
5)使用 QAxWidget 的注意點
這樣顯示普通的JavaScript腳本是沒啥問題的,但是當參考jQuery等js的封裝庫的時候會無法決議,提示如下:


原因是該控制元件默認使用的版本是IE7的兼容模式,對jq不怎么支持,需要指定控制元件加載的IE內核版本來解決這個問題,有修改注冊表,HTML中強制指定等方法,詳細可參考:
WebBrowser控制元件默認使用IE9,IE10的方法
我的用途是加載本地HTML檔案,所以選用里面最簡便的方法是在.html檔案添加下面的指定:
在html頭 加標簽 強制使用最新的ie渲染
<meta http-equiv="X-UA-Compatible" content="IE=edge">
或者強制使用最新的ie11渲染
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE11"/>
然后可以正常顯示本地HTML頁面了,
更多QAxWidget 資料
參考:
鏈接1
鏈接2
鏈接3
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/132166.html
標籤:其他
上一篇:mongoose學習記錄(js中連接資料庫,并進行增刪改查)
下一篇:近日所想
