Create simple starter menu QtQick/QML - qt

I want to create menu of buttons in QML with simple animation
Simple QML Menu
When I add a button after another I only get the last one
Edit: I added this code also but everytime I click any button the menu disappears
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.15
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
Menu {
id: menu
visible: true
MenuItem {
Button{
text:"Play"
}
}
MenuItem {
Button{
text:"Play"
}
}
MenuItem {
Button{
text:"Sett"
}
}
}
}

A MenuItem already derives from AbstractButton, so there's no point in adding a Button as a child of the MenuItem.
The docs show many simple examples, like this:
Menu {
id: menu
MenuItem {
text: "New..."
onTriggered: document.reset()
}
MenuItem {
text: "Open..."
onTriggered: openDialog.open()
}
MenuItem {
text: "Save"
onTriggered: saveDialog.open()
}
}

Related

Why does my Custom QML Tooltip have no background?

I have created a custom tooltip style using this guide: https://doc.qt.io/qt-6/qtquickcontrols2-customize.html#creating-a-custom-style
here is ToolTip.qml within my style:
import QtQuick.Templates 2.0 as T
import QtQuick
T.ToolTip {
id: ctrl
contentItem: Text{
color: "red"
text: ctrl.text
}
background: Rectangle {
color: "blue"
border.color: "yellow"
}
}
And here is how I use it:
import QtQuick.Controls 2.15
import QtQml 2.15
import QtQuick.Layouts 2.15
import QtQuick
ApplicationWindow {
id: mainWindow
visible: true
width: 800
height: 600
visibility: Window.Maximized
Button {
anchors.centerIn: parent
id: button
text: "Click me"
onClicked: {
console.log("Clicked")
}
ToolTip.visible: hovered
ToolTip.text: "hello world"
}
}
The text colour works, but the background doesn't.
Why does it not show the blue background rectangle?
I am using Qt6 with PySide6.
*edit:
I have tried using TextMetrics to give the background a width and height. Is this the idiomatic way to do it? It feels like I shouldn't need text metrics. This also leaves the Label uncentered in the background, which looks bad.
import QtQuick.Templates 2.0 as T
import QtQuick
import QtQuick.Controls
T.ToolTip {
id: ctrl
contentItem: Label {
color: "red"
text: ctrl.text
}
background: Rectangle {
id: bg
color: "yellow"
width: tmet.width + 5
height: tmet.height + 5
}
TextMetrics {
id: tmet
font: ctrl.font
text: ctrl.text
}
}
Everytime I need to create custom controls I'll look into the QtQuick Basic style. On my machine I can find it here Qt/6.4.0/gcc_64/qml/QtQuick/Controls/Basic/ToolTip.qml
Templates are non-visual implementations of controls' logic and
behavior.
You need to set a size on the ToolTip. Look how they are setting the implicitWidth and implicitHeight of the ToolTip.
import QtQuick
import QtQuick.Controls.impl
import QtQuick.Templates as T
T.ToolTip {
id: control
x: parent ? (parent.width - implicitWidth) / 2 : 0
y: -implicitHeight - 3
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
contentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
contentHeight + topPadding + bottomPadding)
margins: 6
padding: 6
closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutsideParent | T.Popup.CloseOnReleaseOutsideParent
contentItem: Text {
text: control.text
font: control.font
wrapMode: Text.Wrap
color: control.palette.toolTipText
}
background: Rectangle {
border.color: control.palette.dark
color: control.palette.toolTipBase
}
}
To set the toolTip text color, it is not necessary to define a custom contentItem Label component. You can change the tooltip color by setting palette.toolTipText.
I can see your use case is to try to apply a custom ToolTip style so that all your components will inherit.
[EDIT: Change the direction of my answer to a custom Button instead of changing the default ToolTip style]
Alternatively, consider implementing custom components that have a custom ToolTip style. e.g. instead of Button, consider having MyButton. This way, we leave the default Button with the default style.
import QtQuick
import QtQuick.Controls
Page {
MyButton {
anchors.centerIn: parent
id: button
text: "Click me"
onClicked: {
console.log("Clicked")
}
ToolTip.visible: hovered
ToolTip.text: "hello world"
}
}
// MyButton.qml
import QtQuick
import QtQuick.Controls
Button {
ToolTip {
visible: parent.hovered
text: parent.ToolTip.text
palette.toolTipText: "red"
background: Rectangle {
color: "lightsteelblue"
border.color: "yellow"
}
}
}
You can Try it Online!

How to align button text

I have a button with some text which is normally centered, but I want this text to align to the left. I have tried some things but they don't seem to work. Is this possible, if yes how can it be done?
import QtQuick 2.15
import QtQuick.Window 2.2
import QtQuick.Controls 2.15
Window {
id: window
visible: true
height: 400
width: 400
Button {
id: button
text: "Align me to the left"
//horizontalAlignment: Text.AlignLeft
width: parent.width
height: 30
flat: true
onClicked: {
console.log("You clicked me")
}
}
}
To customize a Button, you can override the contentItem and/or background properties. If you want left-aligned text, just use the contentItem to create a Text object that looks the way you want it.
Button {
id: button
contentItem: Text {
text: button.text
font: button.font
horizontalAlignment : Text.AlignLeft
}
...
}
Button {
id: button
contentItem: Text {
text: "Align me to the left"
horizontalAlignment : Text.AlignLeft
}
width: parent.width
height: 30
flat: true
onClicked: {
console.log("You clicked me")
}
}

Show only part of Qt Qml Drawer

I want to show only half of a QML Drawer. The idea is to keep some important information in the visible part of the drawer and then let the user show the full drawer with more information.
From the documentation I thought that the
position property should be suitable for this:
Drawer {
modal: false
interactive: false
position: 0.5 // does not work
}
But setting the position does not have an effect. Is it possible to show only a part of the drawer?
As mentioned in my comment, you may want to turn your concept inside out, and have the Drawer inherit its size from its contents, and have the contents change, rather than hardcode its size and manipulate its position.
Here is a full example that shows the idea. The drawer contains a RowLayout which contains "info" and "extra info" - the extra info's visibility is toggled via interaction, and thus changes the size of the drawer, which always stays at the 100% open position, but changes width automatically.
import QtQuick 2.12
import QtQml 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
Window {
id: root
width: 640
height: 480
visible: true
Drawer {
id: drawer
height: root.height
// width automatically derived from RowLayout child's implicitWidth
onClosed: detailed.visible = false
RowLayout {
height: parent.height
spacing: 0
Rectangle {
id: detailed
color: "lightcyan"
Layout.fillHeight: true
Layout.preferredWidth: 200
visible: false // when not visible, this does not add to the RowLayout's implicitWidth
Text {
anchors {
centerIn: parent
}
text: "Extra Info\n Click to close"
}
MouseArea {
anchors {
fill: parent
}
onClicked: {
detailed.visible = false
}
}
}
Rectangle {
color: "lightpink"
Layout.fillHeight: true
Layout.preferredWidth: 200
Text {
anchors {
centerIn: parent
}
text: "Regular Info\n Click to open extra info"
}
MouseArea {
anchors {
fill: parent
}
onClicked: {
detailed.visible = true // toggling visibility automatically makes the Drawer wider
}
}
}
}
}
MouseArea {
id: mouse
anchors {
fill: parent
}
onClicked: {
drawer.open()
}
}
Text {
anchors {
centerIn: parent
}
text: "Click to open drawer"
}
}

QML: how to hide submenu?

I have some menu and this menu contains submenu. In some cases this submenu should be visible. In other cases this submenu should be invisible. How to do this?
I try to use visible property, but it does not work. The submenu is always visible. In code example below submenu should be visible if we click left mouse button and invisible if we click right mouse button. But it is visible in both cases.
import QtQuick 2.13
import QtQuick.Window 2.13
import QtQuick.Controls 2.13
Window {
visible: true
width: 640
height: 480
property bool visibleSubMenu : false
Menu {
id: contextMenu
MenuItem {
text: "Menu item"
}
Menu {
title: "Sub menu"
visible: visibleSubMenu
MenuItem {
text: "Sub menu item"
}
}
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
if (mouse.button === Qt.RightButton)
visibleSubMenu = false;
else
visibleSubMenu = true;
console.log(visibleSubMenu)
contextMenu.popup()
}
}
}
The Menu(QQuickMenu) is an element that saves the information but it is not a visual element, the visual element is its parent that is a MenuItem(QQuickMenuItem) so you must hide the parent:
property bool visibleSubMenu : true
onVisibleSubMenuChanged: sub_menu.parent.visible = visibleSubMenu
Menu {
id: contextMenu
MenuItem {
text: "Menu item"
}
Menu {
id: sub_menu
title: "Sub menu"
MenuItem {
text: "Sub menu item"
}
}
}

Cannot assign to non-existent property

I am trying to make a very simple program to learn how to define custom QML types for reuse. I'm not sure why I'm getting the following error:
Cannot assign to non-existent property "color"
I have searched for an answer and have not found anything that solves it.
Below is the code. Qt underlines color and radius in red, meaning that it is being flagged as an "invalid property name."
//Button.qml
import QtQuick 2.3
Rectangle {
width: 100; height: 100
color: "red"
MouseArea {
anchors.fill: parent
onClicked: console.log("button clicked!")
}
}
//main.qml
import QtQuick 2.3
import QtQuick.Controls 1.2
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
menuBar: MenuBar {
Menu {
title: qsTr("File")
MenuItem {
text: qsTr("&Open")
onTriggered: console.log("Open action triggered");
}
MenuItem {
text: qsTr("Exit")
onTriggered: Qt.quit();
}
}
}
Column {
Button {width: 50; height: 50}
Button { x: 50; width: 100; height: 50; color: "blue" }
Button { width: 50; height: 50; radius: 8}
}
}
Qt Quick Controls has a Button type, and so do you. Apparently the Button from the Qt Quick Controls import (which has no radius or color property) gets chosen over your local file. You have a few options:
Rename your Button type to something else.
Import Qt Quick Controls into a namespace.
Import your type into a namespace.
Here's how you'd do option #2:
import QtQuick 2.3
import QtQuick.Controls 1.2 as Controls
Controls.ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
menuBar: Controls.MenuBar {
Controls.Menu {
title: qsTr("File")
Controls.MenuItem {
text: qsTr("&Open")
onTriggered: console.log("Open action triggered")
}
Controls.MenuItem {
text: qsTr("Exit")
onTriggered: Qt.quit()
}
}
}
Column {
Button {
width: 50
height: 50
}
Button {
x: 50
width: 100
height: 50
color: "blue"
}
Button {
width: 50
height: 50
radius: 8
}
}
}

Resources