2013年11月5日火曜日

QQuickViewを子にもつQDialogをrootObjectのサイズで固定する方法はないものか・・・

艦コレ絶賛はまり中の隠者です。

先ほど、初めて撃沈を体験しました。改造直前だし、中破だけどイベントボス戦だから、いけるかなと思ったのですけど、がっかりです。最後にスクリーンショットとっておくべきでしたね・・・。

さて、そんな艦コレ専用ブラウザの艦メモですが、先日の記事に載せたように、タイマーダイアログが英語版だとうまくダイアログ内に収まっていませんでした。


このTimer Dialogですが、QDialogの中にQQuickViewを入れてあり、実際のダイアログはQMLで作成されています。Setで呼ばれる一覧等は、先日の日記の伊織さんのコメントから、ダウンロードされている事がわかりました。

で、このQDialogですが、uiファイルでサイズが固定にされていました。
しかし、後からQMLを変更したり、フォントなどの関係で、どうしてもQML部のサイズが事前に固定できない場合が出てきます。

さらにtimerDialog.qmlのrootのRectangleはサイズ指定がありません。内部のColumnに表示されるItemの分だけ自動でサイズが決まるようです。

QQuickViewの内部のコンテンツサイズを取得するにはどうしたらよいのでしょうか。QQuickView::rootObjectで、rootのQQuickItemを取得し、QQuickItem::childrenRect()を取り出せば、子のRectが入手できます。あとは、そのsizeに適度なマージンを入れて、QDialogのsetMinimumSizeとsetMaximumSizeに設定してあげれば、QMLのサイズに合わせてダイアログのサイズを固定できそうです。

void TimerDialog::showEvent(QShowEvent *event)
{
    Q_UNUSED(event);
    if(m_viewer == NULL){
        m_viewer = new QtQuick2ApplicationViewer(windowHandle());
        connect(m_viewer->engine(), SIGNAL(quit()), this, SLOT(closeQml()));

        //C++のデータをQML側へ公開
        m_viewer->rootContext()->setContextProperty("timerData", &m_timerdata);

        //QML設定して表示
        m_viewer->setSource(QUrl("qrc:///qml/KanmusuMemory/timerDialog.qml"));
        m_viewer->show();
        QSize contentSize = m_viewer->rootObject()->childrenRect().toRect().size() + QSize(DIALOG_MARGIN,DIALOG_MARGIN);
        setMinimumSize(contentSize);
        setMaximumSize(contentSize);
    }

}

childrenRectは、RectFを返すので、toRect()でRect化した後、size()を取って、それにマージンを加えています。

Githubには入れておきましたが、まだMacでしか確認していないので、修正をWindowsとLinuxで確認したらpull Requestしてみますか。