Tomilov Anatoliy
Tomilov Anatoliy

Reputation: 16691

Non-native Dialog in Qt Quick 2 application

How to make dialogs from import QtQuick.Dialogs to be non-native, non-QDialog-derived (QFileDialog etc)?

It is possible to make QFileDialog to be non-native (QFileDialog::Option::DontUseNativeDialog). But how to make dialogs in QML to be rendered on xcb QPA and on eglfs QPA in the similar way?

Upvotes: 1

Views: 1716

Answers (1)

Mitch
Mitch

Reputation: 24386

Changing this

QApplication app(argc, argv);

to this

QGuiApplication app(argc, argv);

does the trick for Dialog, but not FileDialog. It essentially tells QtQuick.Dialogs that you're not using widgets, but it also affects the style that is used.

The code that checks which application is in use is here:

static QString defaultStyleName()
{
    //Only enable QStyle support when we are using QApplication
#if defined(QT_WIDGETS_LIB) && !defined(Q_OS_IOS) && !defined(Q_OS_ANDROID) && !defined(Q_OS_BLACKBERRY) && !defined(Q_OS_QNX) && !defined(Q_OS_WINRT)
    if (QCoreApplication::instance()->inherits("QApplication"))
        return QLatin1String("Desktop");
#elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
    if (QtAndroidPrivate::androidSdkVersion() >= 11)
        return QLatin1String("Android");
#elif defined(Q_OS_IOS)
    return QLatin1String("iOS");
#elif defined(Q_OS_WINRT) && 0 // Enable once style is ready
    return QLatin1String("WinRT");
#endif
    return QLatin1String("Base");
}

void QQuickAbstractDialog::setVisible(bool)) seems to control which type of dialog is shown. I'm not sure if there's a way to force non-native Dialogs using public QML API, but you could always patch Qt:

diff --git a/src/dialogs/qquickabstractdialog.cpp b/src/dialogs/qquickabstractdialog.cpp
index ce87d56..416f796 100644
--- a/src/dialogs/qquickabstractdialog.cpp
+++ b/src/dialogs/qquickabstractdialog.cpp
@@ -81,7 +81,7 @@ void QQuickAbstractDialog::setVisible(bool v)
     if (m_visible == v) return;
     m_visible = v;

-    if (m_dialogHelperInUse || v) {
+    if (0 /*m_dialogHelperInUse || v*/) {
         // To show the dialog, we first check if there is a dialog helper that can be used
         // and that show succeeds given the current configuration. Otherwise we fall back
         // to use the pure QML version.

This patch alone is enough to force the QML dialog implementations to be used.

For FileDialog, there is this paragraph that explains the process:

The implementation of FileDialog will be a platform file dialog if possible. If that isn't possible, then it will try to instantiate a QFileDialog. If that also isn't possible, then it will fall back to a QML implementation, DefaultFileDialog.qml. In that case you can customize the appearance by editing this file. DefaultFileDialog.qml contains a Rectangle to hold the dialog's contents, because certain embedded systems do not support multiple top-level windows. When the dialog becomes visible, it will automatically be wrapped in a Window if possible, or simply reparented on top of the main window if there can only be one window.

Upvotes: 2

Related Questions