Use MenuBar component in a QQuickView on Windows - windows

I am building a QML application that must work on Windows and Mac OS X. I want to manage the menus in QML so I started using the MenuBar component in my application. I am using a QQuickView in C++ to display my QML elements. My menus appear properly on Mac OS X but I get nothing displayed on Windows and no errors in the logs.
The documentation speaks about this component being linked to ApplicationWindow but as it was working fine on Mac OS I was hoping it would work the same anywhere.
Is there a way to fix this on Windows ?

It seems that QQuickView is not able to contain ApplicationWindow as a root object.
Have you tried to use QQmlApplicationEngine instead of QQuickView?
#include <QtGui/QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine("qml/untitled/main.qml");
QObject* root = engine.rootObjects().at(0);
static_cast<QWindow*>(root)->show();
return app.exec();
}
I faced with the same issue on Windows, and it helped me.

I had a look at the way this is done in the QML ApplicationWindow component and found a way to display my menu on Windows. The idea/hack is to use the property __contentItem of the MenuBar component and attach it to the root element. I also do this only if the menu is not native so that it works as it did before on Mac OS X.
TopMenu.qml
import QtQuick 2.1
import QtQuick.Controls 1.0
MenuBar {
Menu {
title: "Window"
MenuItem {
text: "SubMenu3"
shortcut: "Ctrl+s"
}
MenuItem {
text: "SubMenu2"
shortcut: "Ctrl+p"
}
MenuItem {
text: "Preferences"
shortcut: "Ctrl+,"
}
}
}
RootElement.qml
import QtQuick 2.1
Rectangle {
id: rootWindow
width: 400
height: 400
Item {
id: menuWrapper
anchors.fill: parent
TopMenu {
id: myTopMenu
}
states: State {
name: "hasMenuBar"
when: myTopMenu && !myTopMenu.__isNative
ParentChange {
target: myTopMenu.__contentItem
parent: rootWindow
}
PropertyChanges {
target: myTopMenu.__contentItem
x: 0
y: 0
width: menuWrapper.width
}
}
}
}

Related

How to handle system Dark mode in QML

I'm using QML + Python to create a multi-platform application. Facing a challenge with handling System Dark Mode (not sure if it applies to Windows, but I'm currently using a Mac).
For now I do set Dark / Light mode manually, using property. Is there any way I can detect user's mode and set this value to my property? Or are there any other possible solutions?
import QtCore
import QtQuick
import QtQuick.Controls
import QtQuick.Dialogs
ApplicationWindow {
width: 640
height: 480
visible: true
property bool darkMode: false
Text {
id: textField
color: {
switch (darkMode) {
case true:
"white";
break;
case false:
"black";
break;
}
}
}
}

Qml : switch qml view

I'm a beginner in QML.
I have a Loading.qml and a main.qml
I want to display the loading.qml at the application starting, and when all my data are ready, I want to hide the loading.qml and display the main.qml
I want to do that from c++ code
How can I do that ?
Thank you
[UPDATE]
I have tried this
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterType<MyWindow>("project.mywindow", 1, 0, "MyWindow");
engine.load(QUrl("qrc:/LoadingPage.qml"));
if(engine.rootObjects().isEmpty()) return -1;
// simulate preloading data
std::this_thread::sleep_for(std::chrono::seconds(5));
engine. ? -> switch to another view ?
/*engine.load(QUrl("qrc:/main.qml"));
if(engine.rootObjects().isEmpty()) return -1;*/
return app.exec();
}
My QML
LoadingPage.qml
import QtQuick 2.0
import QtQuick.Window 2.0
import QtQuick.Controls 2.0
ApplicationWindow {
id: loading
visible: true
width: Screen.desktopAvailableWidth
height: Screen.desktopAvailableHeight
title: qsTr("Board")
Loader {
id: pageLoader
}
Component.onCompleted: {
pageLoader.source = "qrc:/main.qml"
loading.visible = false
}
Image {
id: logo
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
width: 100
height: 100
source: "qrc:/img/download.jpeg"
}
Button {
id: btn
width: 250
height: 250
x: 250
y: 0
onClicked: {
pageLoader.source = "qrc:/main.qml"
loading.visible = false
}
}
}
I want to when my main.qml is ready (when c++ construction of my class MyWindow) is ok, I want to switch to them.

QML Keys.onReleased fire when pressing key

Env:
Qt 5.13 + Mingw32 + Windows 10 64bit
or
Qt 5.11 + Mingw32 + Windows 10 64bit
Demo code:
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Item {
id: name
anchors.fill: parent
focus: true
Keys.onReleased: console.log("onReleased")
}
}
Problem: QML Keys.onReleased fire when pressing key(Any Key)
From running your example I assume your problem occurs after holding the Key.
To prevent that you can simply check the isAutoRepeat attribute when you catch the KeyEvent:
Keys.onReleased: if (!event.isAutoRepeat) console.log("onReleased")
You can check isAutoRepeat from event
Item {
id: name
anchors.fill: parent
focus: true
Keys.onReleased: {
if (!event.isAutoRepeat)
console.log("released")
else
console.log("repeated like in a text field")
}
}

Qml Qt Quick Control 2: Font size difference between Text and ComboBox

Let's look at this very simple sample application, built with QT 5.9 on a Windows 10:
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
ColumnLayout {
anchors.left: parent.left
anchors.leftMargin: 20
anchors.right: parent.right
anchors.rightMargin: 20
Text {
id: text
text: "This is a sample Text"
}
ComboBox {
model: [
"A",
"B",
"C"
]
}
Text {
text: "Another Text"
}
TextField {
anchors.left: parent.left
anchors.right: parent.right
text: "User Input"
}
}
}
If I run it without any further modifications from the QT Creator, I get a very weird relationship between the Font-Size of the Text and the ComboBox and TextField blocks. It looks like this:
The text is too small, and the ComboBoxes (and their Fonts) are HUGE.
If I change the main function to set the default font size explicitely to the system font size using this code (It's the same when I hardcode the setPointSizeF to 12, which is the supposed standard size on windows):
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
auto font = app.font();
QFontInfo fi(font.defaultFamily());
font.setPointSizeF(fi.pointSizeF());
app.setFont(font);
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
It looks like this:
Now the "Relative Dimensions" are more balanced, but overall everything is just "too big". Additionally, if I'm opening the ComboBox, I get again very small text:
Did I miss to set some default here? How can I achieve a more balanced look that fit's better into the Operating Systems' native font sizes?
The combobox delegates use a different font to the application default.
Delegate font can be changed to match the rest of the application as follows:
ComboBox {
id: control
delegate: ItemDelegate {
width: control.width
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData
font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal
font.family: control.font.family
font.pointSize: control.font.pointSize
highlighted: control.highlightedIndex === index
hoverEnabled: control.hoverEnabled
}
}
Leave the font sizes as defaults and instead set the widths of your items. You could explicitly set the width of the ComboBox and TextField, or if you want to use the ColumnLayout to have consistent sizing of all the items, see example below,
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
ColumnLayout {
anchors.left: parent.left
anchors.leftMargin: 20
width: text.width
Text {
id: text
text: "This is a sample Text"
}
ComboBox {
Layout.fillWidth: true
model: [
"A",
"B",
"C"
]
}
Text {
text: "Another Text"
}
TextField {
Layout.fillWidth: true
text: "User Input"
}
}
}
You can simply try setting: font.pointSize: 12 in both the combobox and text fields. This works for me on Qt 5.9 in Windows 10. I am still trying to figure how to change the font size inside the combobox drop down; will expand this answer when I know.

Qt4: QMenuBar/QMenu doesn't show up on Mac OS X

I'm having difficulties to make a QMenuBar display a QMenu with a QAction under Mac OS X (Snow Leopard).
Here is the code I'm using for creating the menu:
void ClientWindow::setUpMenu ()
{
QMenu * file = menuBar()->addMenu("&File");
QAction * quit = new QAction("&Quit", this);
file->addAction(quit);
connect(quit, SIGNAL(triggered()), this, SLOT(quit()));
}
Here is the ClientWindow class interface:
class ClientWindow : public QMainWindow
{
public:
ClientWindow (QWidget * parent = 0);
void setUpMenu ();
};
And here is my main() method:
int main (int argc, char * argv[])
{
QApplication app(argc, argv);
ClientWindow window;
window.setUpMenu();
window.show();
return app.exec();
}
Any ideas why it wouldn't show up on the menu bar?
Thank you all.
I solved the problem.
It appears that there is one action called "Quit" already, which is part of the default application's menu (every Mac OS X GUI app has such menu). This causes my attempt to add another action called "Quit" to be ignored by either Qt or the Window Server.
Simply renaming the action to "Close" solved the problem.
Some menupoints are automatically mapped to the mac osx native menu:
see http://doc.trolltech.com/4.6/mac-differences.html#menu-bar

Resources