QtQuick button shows outside of dialog - qt

I'm trying to make a customizable single button error message dialog in QtQuick, but when I open the dialog the "Ok" button is shown outside of it:
it looks like this
When I open the dialog again, it works normally, the button is shown at the right place.
Here is a minimal working example :
import QtQuick 2.11
import QtQuick.Window 2.11
import QtQuick.Controls 2.4
Window {
visible: true
width: 640
height: 480
Button {
text: "Open Dialog"
onClicked: {
dialog.show("This text can be customized.")
}
Dialog {
id: dialog
standardButtons: Dialog.Ok
title: "Error"
modal: true
function show(txt) {
label.text = txt
open()
}
Label {
id: label
}
}
}
}
I'm using Qt 5.11.3 with QtQuick 2.11, build target is Desktop GCC 64 bits.
Is this a bug? What am I doing wrong?

It seems to be a bug in Qt 5.11.3 or in my installation of it on Linux.
Here is the workaround I used, basically recreating the Dialog from a regular Popup :
import QtQuick 2.0
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.3
Popup {
x: (parent.width-width)/2
y: (parent.height-height)/2
modal: true
closePolicy: Popup.NoAutoClose
property var title: "Error"
property var msg: ""
function show(message) {
msg = message
open()
}
ColumnLayout {
spacing: 30
Label {
Layout.alignment: Qt.AlignLeft
Layout.preferredHeight: 5
font.bold: true
text: title
}
Label {
text: msg
}
Button {
Layout.alignment: Qt.AlignRight
text: "Ok"
onClicked: {
close()
}
}
}
}

Related

Qml menu popup latency

When my mouse event happened,the menu can popup,but not immediately,it seems a little latency. this is my code, is anything wrong?
My Qt version is 5.15, my system is Windows 10.
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.12
Window {
visible: true
width: 450
height: 350
title: qsTr("ListView")
property bool refreshFlag: false
Rectangle {
id: rightview
width: 60
height: 300
x: 100
color: "#EEEEEE"
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton | Qt.LeftButton
onClicked: {
console.log(width)
if (mouse.button === Qt.RightButton)
contextMenus.popup()
}
Menu {
id: contextMenus
MenuItem { text: "open" }
MenuItem { text: "save " }
MenuItem { text: "else..." }
}
}
Text {
font.pointSize: 12
text: "content"
}
}
}
this is my screenshot
A couple of issues with your program snippet:
Don't mix QtQuick.Controls 1.x with QtQuick.Controls 2.x
Recommend you update all your references to versions to 2.15
Do not declare Menu inside MouseArea, it doesn't make sense
The MouseArea can be optimized to only accept the RightButton
Declare the Menu at the "top level"
Here's a cleanup of your code:
import QtQuick 2.15
import QtQuick.Controls 2.15
Page {
anchors.fill: parent
Rectangle {
x: 100
width: 60
height: 300
color: "#EEEEEE"
Text {
font.pointSize: 12
text: "content"
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: contextMenus.popup()
}
}
Menu {
id: contextMenus
MenuItem { text: "open" }
MenuItem { text: "save " }
MenuItem { text: "else..." }
}
}
You can Try it Online!
There appears to be no performance issue when I run the above snippet using qmlonline. I don't think the code is an issue. I think we need to get an understanding of:
Your version of Qt
Your platform (i.e. OS, hardware, etc)

Assign MenuItem.Shortcut give Invalid attached object assignment

The following code:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.5
import QtQuick.Controls.Styles 1.4
Window {
visible: true
width: 640
height: 480
title: qsTr("This is my application title!")
ColumnLayout
{
id: col1
spacing: 2
MenuBar
{
Menu {
title: "File"
MenuItem {
text: "Open"
Shortcut: "Ctrl+O"
onTriggered: console.log("Ctrl+O trigged")
}
MenuItem { text: "Paste link from Ctrl+V" }
MenuItem { text: "Save log as" }
}
Menu { title: "Help" }
Menu { title: "About" }
Menu { title: "Exit" }
}
}
Give the following error:
qrc:/main.qml:25:21: Invalid attached object assignment
the line on error is Shortcut: "Ctrl+O". The Qt documentation give example like this. What am I missing?
edit: added documentation link.
edit 2: updated imports
In qml there are at least 2 groups of controls:
Qt Quick Controls 1
Qt Quick Controls 2
These groups have components with the same one that is the cause of your error since you try to apply the property of the MenuItem from one group to another (check the imports so that you realize the error).
QQC1 MenuItem
QQC2 MenuItem
Depending on which group you want to use, there are different options:
Qt QuickControls 1
import QtQuick 2.12
import QtQuick.Controls 1.4
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("This is my application title!")
menuBar: MenuBar{
Menu {
title: "File"
MenuItem {
text: "Open"
shortcut: "Ctrl+O"
onTriggered: console.log("Ctrl+O trigged")
}
MenuItem{ text: "Paste link from Ctrl+V" }
MenuItem { text: "Save log as" }
}
Menu { title: "Help" }
Menu { title: "About" }
Menu { title: "Exit" }
}
}
Qt QuickControls 2
import QtQuick 2.12
import QtQuick.Controls 2.12
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("This is my application title!")
menuBar: MenuBar{
Menu {
title: "File"
Action {
text: "Open"
shortcut: "Ctrl+O"
onTriggered: console.log("Ctrl+O trigged")
}
Action { text: "Paste link from Ctrl+V" }
Action { text: "Save log as" }
}
Menu { title: "Help" }
Menu { title: "About" }
Menu { title: "Exit" }
}
}
Possibly you are going to have a similar problem with styles so it is recommended that you read this answer where I point out that using namespace can be a solution if you want to combine components of both modules.
Note: QML is case sensitive, in the docs you indicate it indicates shortcut but you use Shortcut.

How to open a dialog from a MenuBar QML

I'm trying to open a "About" dialog from the menubar.
I have a MainMenuBar.qml that looks like this:
import QtQuick 2.12
import './dialogs'
Labs.MenuBar {
// Various menus omitted
AboutDialog {
id: about_dialog
}
Labs.Menu {
title: qsTr('&Help')
Labs.MenuItem {
text: qsTr('&About')
onTriggered: about_dialog.open()
}
}
}
And my AboutDialog.qml:
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
Dialog {
title: qsTr('id_about')
width: 500
height: 350
standardButtons: Dialog.Ok
Page {
anchors.fill: parent
header: RowLayout {
Image {
Layout.margins: 16
source: "../ic_home.png"
}
}
Label {
anchors.fill: parent
anchors.margins: 32
wrapMode: Text.WordWrap
text: qsTr("Hello world")
}
}
}
When clicking "About" I get:
/src/MainMenuBar.qml: QML Dialog: cannot find any window to open popup in.
I suppose that happens because I am opening it from the menubar and not from a window - is that possible? What should I do?
Nevermind, I figured it out.
AboutDialog.qml shouldn't be declared in MainMenuBar.qml, should be declared in main.qml instead.
MainMenuBar.qml
import QtQuick 2.12
import './dialogs'
Labs.MenuBar {
// Various menus omitted
Labs.Menu {
title: qsTr('&Help')
Labs.MenuItem {
text: qsTr('&About')
onTriggered: about_dialog.open()
}
}
}
main.qml
Item {
MainMenuBar { }
AboutDialog {
id: about_dialog
}
}

How should I start QML files?

I have 4 QML files: MainMenu.qml, AppArea.qml, Result.qml and main.qml.
When my app starts, I want to see first page as MainMenu.qml fullscreen. There is a button (on MainMenu.qml) to start AppArea.qml. When I click the the button, I want to start AppArea.qml as fullscreen new window.
There is a button (on AppArea.qml), when I click that button, I want to show Result.qml but I want to see Result.qml on AppArea.qml, I mean when Result.qml come outs, AppArea.qml will not disappear but Result.qml will appear on AppArea.qml.
There is a button on Result.qml. When I click the button, the Repeater in AppArea.qml will regenerate, because maybe model of Repeater changing like 1, 2, 3, 4.... There is a button on AppArea.qml, when I click the button, I want to open MainMenu.qml as a fullscreen new window like AppArea.qml.
Actually you can think basic: My app is a game like this:
How way should I choose for these jobs?
In addition to the mentioned post, in your case you are using the component from qml file, so you need to load the component first, your main.qml can be like this:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
Window {
id: mainWindow
title: "Main window"
visible: true
flags: Qt.Dialog
modality: Qt.ApplicationModal
Loader{
id: mainMenuLoader
}
Component.onCompleted: {
mainMenuLoader.source="mainMenu.qml"
var mainMenu = mainMenuLoader.item.createObject(mainWindow);
mainWindow.hide()
}
}
and your mainMenu.qml can look like this:
import QtQuick 2.9
import QtQuick.Window 2.3
import QtQuick.Controls 2.2
Component {
id: mainMenu
Window {
id:mmenu
title: "Main Menu"
width: 600
height: 600
visible: true
flags: Qt.Dialog
modality: Qt.ApplicationModal
Loader{
id: appAreaLoader
}
Text {
text: "This is mainMenu"
}
Button{
id: loadAppArea
anchors.centerIn: parent
text: "Start Game"
onClicked: {
appAreaLoader.source="appArea.qml"
var appArea = appAreaLoader.item.createObject(mainMenu);
hide()
}
}
}
}
you will need to do the same for successive windows ...etc.
While for result, you need to use a MouseArea:
appArea.qml:
Component {
id: appMenu
Window {
id:appMenuWindow
title: "App Menu"
width: 600
height: 600
visible: true
flags: Qt.Dialog
modality: Qt.ApplicationModal
Loader{
id:anotherLoader
visible: true
anchors.left: appMenuText.left
anchors.top: appMenuText.bottom
width: parent.width/3
height: parent.height/3
}
Text {
id: appMenuText
text: "This is App Area"
anchors.centerIn: parent
}
Button{
id: loadResult
text: "Show Result"
onClicked: {
anotherLoader.source = "result.qml"
anotherLoader.visible=true
}
}
Button{
anchors.right: parent.right
id: loadMainMenu
text: "Open main Menu"
onClicked: {
hide()
//mmenu.show()
anotherLoader.setSource("main.qml")
}
}
}
}
result.qml:
Rectangle{
color: "green"
Text {
anchors.centerIn: parent
id: resultxt
text: qsTr("This is result, Click to close")
}
MouseArea {
anchors.fill: parent
onClicked: { anotherLoader.visible = false
}
}
}

How to edit App menu from Qt Creator?

I start "QML App with controls" project in Qt Creator. I see that I can add to canvas different kind of controls, but I do not see how I can in graphical mode edit menu like: File, View, Edit... In constructor on canvas it's simple do not exists, but it's exists of running app, like http://img.ctrlv.in/img/15/10/03/560f856edb26c.png
You can create the menu in the main.qml file, here is an example application:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
ApplicationWindow {
title: qsTr("Hello World")
width: 640
height: 480
visible: true
menuBar: MenuBar {
Menu {
title: qsTr("&File")
MenuItem {
text: qsTr("&Open")
onTriggered: messageDialog.show(qsTr("Open action triggered"));
}
MenuItem {
text: qsTr("Save")
onTriggered: messageDialog.show(qsTr("Save action triggered"));
}
}
Menu {
title: qsTr("&Help")
MenuItem {
text: qsTr("About")
onTriggered: messageDialog.show(qsTr("About: test QML app with menu"));
}
}
}
MainForm {
anchors.fill: parent
button1.onClicked: messageDialog.show(qsTr("Button 1 pressed"))
button2.onClicked: messageDialog.show(qsTr("Button 2 pressed"))
}
MessageDialog {
id: messageDialog
title: qsTr("Message Test")
function show(caption) {
messageDialog.text = caption;
messageDialog.open();
}
}
}

Resources