How to open a dialog from a MenuBar QML - qt

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
}
}

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)

how to load child1.qml page on to main.qml page calling from another_child.qml page

In my MyHeader.qml cannot load the MyChild2.qml. How to load child qml page on to mmain.qml page calling from another child qml page as shown below.
TestProject Folder
qml Folder
Main.qml
MyChild1.qml
mainui Folder
MyHeader.qml
MyChild2.qml
import QtQuick 2.10
import QtQuick.Controls 2.2
import "."
// Main.qml
ApplicationWindow {
id: rootApp
Loader {
id: loaderPage
anchors.fill: parent
}
MyChild1 {
}
}
// MyChild1.qml
import QtQuick 2.10
import QtQuick.Controls 2.2
import "."
Page {
id: myItem1
anchors.fill: parent
MyHeader {
anchors.top: parent.top
}
}
// MyChild2.qml
import QtQuick 2.10
import QtQuick.Controls 2.2
import "."
Page {
id: myItem2
anchors.fill: parent
Rectangle {
anchors.fill: parent
color: "#000000"
}
}
// MyHeader.qml
import QtQuick 2.10
import QtQuick.Controls 2.2
import "."
Rectangle {
id: myHeader
width: parent.width
height: dp(30)
color: "lightblue"
Text {
id: loadQML
text: "Load QML"
color: "#000000"
font.pixelSize: dp(20)
MouseArea {
anchors.fill: parent
onClicked: {
myItem1.visible = false
loaderPage.source = "MyChild2.qml"
loaderPage.Top
}
}
}
}
Using the Loader and Connection I am getting Cannot assign to non-existent property "onPageChanged"
import QtQuick 2.10
import "mainui"
ApplicationWindow {
id: rootApp
signal pageChanged(int page);
Loader {
id:rootLoader
anchors.fill: parent
source: "mainui/Page1.qml"
Connections {
target: rootLoader.item
onPageChanged: {
switch(page)
{
case 1: rootLoader.source = "mainui/Page1.qml"; break;
case 2: rootLoader.source = "mainui/Page2.qml"; break;
}
}
}
}
} // APP
Due to scope limitation of Loader you cannot access items outside it. But you can notify the Loader to do some action. In the example below there are 2 components define a signal. The Loader connects this signal to a handler:
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
id: win
width: 400
height: 400
title: "Test"
visible: true
Component {
id: page1
Rectangle {
signal pageChanged(int page);
anchors.fill: parent
color: "orange"
Text {
anchors.centerIn: parent
text: "PAGE 1\nClick to change"
horizontalAlignment: Text.AlignHCenter
}
MouseArea {
anchors.fill: parent
onClicked: {
pageChanged(2);
}
}
}
}
Component {
id: page2
Rectangle {
signal pageChanged(int page);
anchors.fill: parent
color: "lightblue"
Text {
anchors.centerIn: parent
text: "PAGE 2\nClick to change"
horizontalAlignment: Text.AlignHCenter
}
MouseArea {
anchors.fill: parent
onClicked: {
pageChanged(1);
}
}
}
}
Loader {
id: loader
anchors.fill: parent
sourceComponent: page1
Connections {
target: loader.item
onPageChanged: {
switch(page)
{
case 1: loader.sourceComponent = page1; break;
case 2: loader.sourceComponent = page2; break;
}
}
}
}
}

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
}
}
}

Adding TabButton dynamically to TabBar in QML

I am trying to add a tabButton to TabBar dynamically on pressing a button but i have spent a lot of time searching but i am not getting how to add, below is the code which i am working on :
MyTabButton.qml
import QtQuick 2.4
import QtQuick.Controls 2.2
Item
{
property int BtnWidth:0
property int BtnHeight:0
property string BtnText: ""
property bool isChecked : false
TabButton
{
id:tabBtn
text:BtnText
width:BtnWidth
height:BtnHeight
}
}
MainForm.qml
import QtQuick 2.4
import QtQuick.Controls 2.2
Rectangle
{
Button
{
id:button
width:100
height:100
anchors.top:parent.top
text:qStr("Add")
onClicked{
//How to add logic here to add tab in below tabBar.
}
}
TabBar
{
id:tabBar
anchors.top:button.bottom
width:500
height:500
}
}
Example:
import QtQuick 2.7
import QtQuick.Controls 2.0
ApplicationWindow {
id: window
width: 360
height: 630
visible: true
header: TabBar {
id: tabBar
}
Component {
id: tabButton
TabButton { }
}
Button {
text: "Add"
anchors.centerIn: parent
onClicked: {
var tab = tabButton.createObject(tabBar, {text: "Tab " + tabBar.count})
tabBar.addItem(tab)
}
}
}
You need to have something like a Component that is a TabButton. Your file MyTabButton.qml won't result in a TabButton, but instead an Item containing a TabButton, but with this, your TabBar does not know what to do.
So your file will need to have TabButton as root element
//MyTabButton.qml
import QtQuick 2.4
import QtQuick.Controls 2.2
TabButton
{
id: tabBtn
// customize as you like
}
Then you create a Component of this in your file where you want to use it. (e.g. main.qml)
import QtQuick 2.4
import QtQuick.Controls 2.0
ApplicationWindow {
width: 800
height: 600
visible: true
TabBar {
id: tabBar
width: 800
height: 50
}
// The component is like a factory for MyTabButtons now.
// Use myTabButton.createObject(parent, jsobject-with-property-assignments) to create instances.
Component {
id: myTabButton
MyTabButton {
/// EDIT ACCORDING TO YOUR COMMENTS ***
Connections {
target: tabBar
onCurrentIndexChanged: doSomething()
}
/// EDIT OVER
}
}
Button {
anchors.centerIn: parent
// Create a object out of the component, and add it to the container
onClicked: tabBar.addItem(myTabButton.createObject(tabBar /*, { object to set properties }*/))
}
}
TabBar inherits Container, which has addItem().
Try it in Window
Row {
anchors.fill: parent
TabBar {
id: tabBar
currentIndex: 0
width: parent.width - addButton.width
TabButton { text: "TabButton" }
}
Component {
id: tabButton
TabButton { text: "TabButton" }
}
Button {
id: addButton
text: "+"
flat: true
onClicked: {
tabBar.addItem(tabButton.createObject(tabBar))
console.log("added:", tabBar.itemAt(tabBar.count - 1))
}
}
}

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