I have my simplified application window as the following. It opens a menu when clicked on it and while the menu is open, it is immediately closed when I click anywhere outside of it. I want to learn which specific event or signal causes context menus to close when clicked on their parent? I need to mimic this behavior manually.
ApplicationWindow
{
MouseArea
{
anchors.fill: parent
onClicked:
{
contextMenu.popup()
}
}
Menu
{
id: contextMenu
MenuItem
{
text: "File"
}
}
}
Related
Suppose I have a QML Window that contains a bunch of different controls:
Window {
...
TextEdit { ... }
CheckBox { ... }
Button { ... }
etc
}
Now I want my window to change "mode" on a certain event, and display a completely different set of controls.
Imagine its part of a multi-screen form. The current state is the first page of the form. When the user clicks "Next" button it goes to page 2 of the form. I want to add a new set of controls that represents page 2.
What is the correct way to organize this in QtQuick / QML ?
A common way to do that is with a StackView. The organization would be something like this:
Window {
StackView {
id: stackView
initialItem: page1
}
Item {
id: footerItem
// Maybe add other buttons here too
Button {
id: nextBtn
text: "Next"
onClicked: {
stackView.push(page2);
}
}
}
Component {
id: page1
Page1 {
// Define this in separate Page1.qml file
// This is where your page 1 controls go.
}
}
Component {
id: page2
Page2 {
// Define this in separate Page2.qml file
// This is where your page 2 controls go.
}
}
}
I would probably implement a mode changing view or form with "Back" and "Next" buttons using StackLayout. The StackLayout class provides a stack of items where only one item is visible at a time. You go to the next or previous mode by updating currentIndex.
StackLayout {
id: layout
anchors.fill: parent
currentIndex: 1
Rectangle {
color: 'teal'
implicitWidth: 200
implicitHeight: 200
}
Rectangle {
color: 'plum'
implicitWidth: 300
implicitHeight: 200
}
}
I have StackView in main.qml.I pushed menu.qml file from main.qml using stackview. I'm trying to access stackview in menu.qml file to open new item. Is there a way with which we can push component/items with properties using stackview? My components are basically.qml files for different views
ApplicationWindow {
id: settingsWindow
StackView {
id: stack
initialItem: view
Component {
id: view
MouseArea {
onClicked: stack.push(view)
}
}
}
Button{
id: button1
onClicked: {
stack.pop(StackView.Immediate)
stack.push (Qt.resolvedUrl("menu.qml"))
}
}
}
menu.qml
Item {
Button{
id: button1
onclicked : { stack.push (Qt.resolvedUrl("new.qml")) }
}
}
Assuming you mean you want to access the StackView object from withing pages you pushed on it.
StackView has an attached property, which lets you obtain a reference to the view that owns the page.
Long story short, in Menu.qml you can do:
Item {
id: root
Button {
id: button1
onClicked: { root.StackView.view.push(Qt.resolvedUrl("new.qml")) }
}
}
https://doc.qt.io/qt-5/qml-qtquick-controls2-stackview.html#view-attached-prop
Finally ended up creating each page in StackView as a component property and then pushing each of them using a signal. Added the signal to every page and connected it to main page where stackview existed . This answer helped
https://stackoverflow.com/a/45354861/11288640
I have a listview with a delegate that has MouseArea covering the whole of a delegate. In that MouseArea's onClick slot I specifically set
mouse.accepted = false
but the Combobox from QtQuick.Controls 1.4 that lives in that delegate still refuses to open its popup on clicks. I've tested that combobox should receive the click with:
ComboBox {
id: cbChapters
model: chapters
MouseArea {
anchors.fill: parent
onClicked: {
mouse.accepted = false
console.log("arrived")
}
}
}
And the click events do arrive into this inner mouse area, just not into the combobox itself it seems... what might be the problem?
Answering my own question:
Problem seems to be that MouseArea automatically accepts Pressed events and in the Combobox code itself there's this:
onPressed: {
if (!Settings.hasTouchScreen)
popup.toggleShow()
}
onClicked: {
if (Settings.hasTouchScreen)
popup.toggleShow()
}
So it seems like Clicked requires touchscreen to open the popup(which is not present on the desktop, obviously)
This leaves only Pressed to open the popup, but it's being suppressed at the uppermost MouseArea as it is not a composed event and propagateComposedEvents does nothing for it.
The solution could be :
1) to go through your mouse area chain and in each one of them set:
onPressed: {
mouse.accepted = false
}
2) call popup directly in "clicked" handler
ComboBox {
id: cbChapters
MouseArea {
anchors.fill: parent
propagateComposedEvents: true
onClicked: {
cbChapters.__popup.toggleShow()
}
}
}
I have an application in which i am loading some resources inside a main file with a Loader object:
main.qml:
ApplicationWindow {
property string pageSource: pageLoader.source
...
Loader {
id: pageLoader
source: "page1.qml"
}
}
In page1.qml i have a layout that wraps some buttons and text fields. Loading this page in pageLoader works fine. As you can see i have a foo Button that should switch the source of the Loader to page2.qml, but for some reason it's not working.
page1.qml:
Item {
ColumnLayout {
TexField {...}
TexField {...}
Button {
id: foo
onClicked: {
pageSource = "page2.qml"
}
}
}
}
By checking some console logs i was able to know that i am actually changing the source of the loader, but the view is not updating as expected and all controls from page1.qml is not replaced by page2.qml. This second page has a ListView. Toggling active property of Loader doesn't work either. Can anyone please shed a light?
I want to show a context menu when right-clicking on Qt5.5 qml TreeView item, but it has clicked signal. How to show a context menu on right click?
TreeView {
id: tree_view
anchors.fill: parent
model: tree_model
headerVisible: false
backgroundVisible: false
TableViewColumn {
role: "display"
}
onClicked: {
console.log("clicked", index)
}
onDoubleClicked: isExpanded(index) ? collapse(index) : expand(index)
}
It's actually quite easy, you just need a MouseArea configured to accept only right click events, and it won't interfere with the mouse handling performed by the TreeView itself:
TreeView {
id: tree_view
anchors.fill: parent
model: tree_model
TableViewColumn {
role: "display"
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: {
var index = parent.indexAt(mouse.x, mouse.y)
if (index.valid) {
console.log("show context menu for row: " + index.row)
}
}
}
}
Can you simply define your menu somewhere and use the popup method to show it? That method open the menu near to the mouse cursor, so to the right position.
Of course, you have to define your itemDelegate as well and let the event flows out of your item if needed (do not consume it).
The documentation for the clicked signal of a TreeView explicitly refers to the item delegate to consume those events, so I guess this is the intended approach.