5

Qt 5.5、QWebView プロジェクトを Qt 5.6 (ベータ)、QWebEngine に移植する作業を行っています。ここで移植ガイドを読みました。私のコードは次のようになります。

.h ファイルは _view を次のように定義します。

QWebEngineView* _view;

および .cpp コンストラクター (QWidget から継承するクラス) には次のものがあります。

QVBoxLayout* vbox = new QVBoxLayout(this);
_view = new QWebEngineView(this);
    connect(_view, SIGNAL(loadFinished(bool)), this, SLOT(loadPageFinished(bool)));
QString webDir = getReportBasePath() + no_tr("/index.html#") + startingPage;
//  QWebEnginePage *page = _view->page();   // <-- CRASH!!
_view->load( QUrl("file:///" + webDir ) );  // <-- CRASH!!
_view->show();
vbox->addWidget(_view);

page() または load() メソッドを実行すると、全体が次のようにクラッシュします。

Unhandled exception at 0x67019C66 (Qt5Cored.dll) in qxs.exe: 0xC0000005: 
Access violation reading location 0x00000000.

_view ポインターが null でないことを確認しました。

ドキュメントを見ると、上記のコードとほぼ同じ例がここにあります。また、 load() 呼び出しを彼らのものと同じになるように置き換えてみました:

view->load(QUrl("http://qt-project.org/"));

それでもクラッシュします。これらのクラッシュを引き起こしている可能性のあるアイデアはありますか?

最初に QWebEnginePage を作成し、QWebEngineView で setPage() を作成する必要がありますか? (私はそうではないと仮定しています...) 私が使用している Qt バイナリ (Windows 32 ビット MSVC 2013 用にビルド済み) と何か関係があるのでしょうか?

スタック トレースの関連部分:

    Qt5WebEngineWidgetsd.dll!QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile * _profile) Line 95 C++
    Qt5WebEngineWidgetsd.dll!QWebEnginePage::QWebEnginePage(QObject * parent) Line 393  C++
    Qt5WebEngineWidgetsd.dll!QWebEngineView::page() Line 145    C++
    Qt5WebEngineWidgetsd.dll!QWebEngineView::load(const QUrl & url) Line 157    C++
    qxs.exe!ReportWidget::ReportWidget(QcaMain * qm, QWidget * parent, QString startingPage) Line 321   C++

ここでクラッシュします:

QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
    : adapter(new WebContentsAdapter)
    , history(new QWebEngineHistory(new QWebEngineHistoryPrivate(this)))
    , profile(_profile ? _profile : QWebEngineProfile::defaultProfile())
    , settings(new QWebEngineSettings(profile->settings()))
    , view(0)
    , isLoading(false)
    , scriptCollection(new QWebEngineScriptCollectionPrivate(browserContextAdapter()->userScriptController(), adapter.data()))
    , m_backgroundColor(Qt::white)
    , fullscreenMode(false)
{
    memset(actions, 0, sizeof(actions));
}

_profile が NULL であることと関係があるのではないかと考えたので、最初に QWebEngineProfile を次のように設定しようとしました。

QWebEnginePage* page = new QWebEnginePage(  QWebEngineProfile::defaultProfile(), _view );
_view->setPage( page );

次に、代わりに qwebengineprofile.cpp でクラッシュします:

static QWebEngineProfile* profile = new QWebEngineProfile(
            new QWebEngineProfilePrivate(BrowserContextAdapter::defaultContext()),
            BrowserContextAdapter::globalQObjectRoot());

スタック トレースあり:

    Qt5Cored.dll!convert_to_wchar_t_elided(wchar_t * d, unsigned int space, const char * s) Line 256    C++
    Qt5Cored.dll!qt_message_fatal(QtMsgType __formal, const QMessageLogContext & context, const QString & message) Line 1593    C++
    Qt5Cored.dll!QMessageLogger::fatal(const char * msg, ...) Line 784  C++
    Qt5WebEngineCored.dll!`anonymous namespace'::subProcessPath(void)   C++
    Qt5WebEngineCored.dll!WebEngineLibraryInfo::getPath(int)    C++
    Qt5WebEngineCored.dll!WebEngineContext::WebEngineContext(void)  C++
    Qt5WebEngineCored.dll!WebEngineContext::current(void)   C++
    Qt5WebEngineCored.dll!QtWebEngineCore::BrowserContextAdapter::defaultContext(void)  C++
>   Qt5WebEngineWidgetsd.dll!QWebEngineProfile::defaultProfile() Line 516   C++
4

2 に答える 2

10

問題が解決しました。QWebEngine に必要ないくつかの重要なファイルがありませんでした。そうしないとクラッシュします。これらのファイルは、実行可能ファイルと同じディレクトリにある必要があります。それらは windeployqt.exe ツールによってそこに配置されるため、Qt アプリケーションがクラッシュすることなく実行するために必要なすべてのものを確実に備えているようにするための最良の方法です。

qtwebengine_resources.pak
qtwebengine_resources_100p
qtwebengine_resources_200p.pak.pak
QtWebEngineProcess.exe
icudtl.dat  

これが私を獲得した理由は、私たちの開発グループが以前は Qt 4.8 を使用しており、社内の方法を使用して必要な Qt dll などをターゲット ディレクトリにコピーしたためです。Qt 5.x にアップグレードして QWebEngine を追加したとき、上記のファイルが必要であることを認識していませんでした。

于 2016-02-17T04:40:50.730 に答える