Why Qml Popup modality is ignored? - qt

I have an issue with Popup (default qml class) not being modal, despite modality set to true and closePolicy to NoAutoClose.
The problem occurs when I open the Popup by clicking a standard qml button. After opening Popup, a lengthy operation is performed, then Popup is closed.
When operation is running, whole application and the Popup itself reacts to mouse clicks. But it doesn't close the Popup. Instead it somehow clicks the button, that opened the Popup again. That shouldn't happen since my Popup is modal.
import QtQuick 2.11
import QtQuick.Window 2.11
import QtQuick.Controls 2.4
ApplicationWindow {
id: main_window
visible: true
width: 800
height: 500
Item {
anchors.fill: parent
Popup {
id: blockingPopup
width: 300
height: 50
modal: true
focus: true
closePolicy: Popup.NoAutoClose
}
Button {
text: "Btn"
onClicked: {
console.log("clicked")
blockingPopup.open();
cppModel.lengthyOperation()
blockingPopup.close();
}
}
}
}
To summarize it again: the button is somehow clicked when I click outside (or even inside) the modal Popup when it is displayed and the operation is running.
Qt 5.12.0, Linux Mint 19.2

Problem was in QCoreApplication::processEvents() that was in my cpp model function. It was causing clicks on a modal popup to be registered as clicks on button.

Related

QML BusyIndicator how to overlay the current window, like ProgressDialog in Android

Iam using QML Busyindicator when a user login or loading a data in a page or something like this, I want to be able to make the busyindicator overlay over the current window and make the window not editable, something similar to the messagebox when it shows up and disables all the Window, so I cant interact with the widgets on this window until the loading finish, something like the ProgressDialog in Android.
this is my code and what I try to do, also I tried to use MessageDialog and use this indicator inside it and remove all buttons, but it does not work.
Popup {
id: waitpop
width: 100
height: 100
BusyIndicator {
id: login_progress
running: true
anchors.fill: parent
}
anchors.centerIn: Overlay.overlay
closePolicy: Popup.NoAutoClose
}
this code shows the busy indicator but the user still can interact with the button and text field and everything, so any ideas?
The modal property prevents you from being able to click outside the popup.
Popup {
anchors.centerIn: Overlay.overlay
closePolicy: Popup.NoAutoClose
modal: true
BusyIndicator {
running: true
}
}

WebEngineView variables 'canGoBack' and 'canGoForward' returns wrong values

I'm working on an application that's running on Raspberry Pi 4, and I got this strange behavior of QML's WebEngineView.
I created 3 buttons for going to the main page and for going back and forward:
Button {
id: box_button_main_page
text: "Go to Main Page"
onClicked: mainWebView.url = "https://www.youtube.com/"
}
Button {
id: box_button_go_back
enabled: mainWebView.canGoBack
text: "Back"
onClicked: mainWebView.goBack()
}
Button {
id: box_button_go_forward
enabled: mainWebView.canGoForward
text: "Forward"
onClicked: mainWebView.goForward()
}
It works as expected: the "Back" and "Forward" buttons become grayed at the right points. But, if one makes below actions:
go to any link
go to yet another link
click "Back" button
click "Go to Main Page"
then both "Back" and "Forward" buttons are still enabled. And clicking on "Forward" button does nothing.
I checked in the "Go to Main Page" onClicked action that both canGoBack and canGoForward returns true after setting url property. I tried to search if there is yet another method to order WEV to switch to another page, but there is none :(.
I didn't find on the Net anyone reporting it as a bug, so either I'm doing it wrong, or I actually found a bug >_>
It works with WebAction. Have a look at this demo. All I've done is add the following Button in the ToolBar RowLayout:
Button {
text: "Go to Main Page"
onClicked: webEngineView.url = "https://www.youtube.com/"
}
Here is a full example using WebAction:
import QtQuick 2.15
import QtQuick.Window 2.15
import QtWebEngine 1.10
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
ApplicationWindow {
id: window
visible: true
width: 800
height: 600
title: qsTr("WebEngineAction Example")
header: ToolBar {
RowLayout {
anchors.fill: parent
Button {
text: "Go to Main Page"
onClicked: webEngineView.url = "https://www.youtube.com/"
}
Button {
property int itemAction: WebEngineView.Back
text: "Back"
enabled: webEngineView.action(itemAction).enabled
onClicked: webEngineView.action(itemAction).trigger()
}
Button {
property int itemAction: WebEngineView.Forward
text: "Forward"
enabled: webEngineView.action(itemAction).enabled
onClicked: webEngineView.action(itemAction).trigger()
}
}
}
WebEngineView {
id: webEngineView
url: "https://qt.io"
anchors.fill: parent
}
}

Popup in qml : (closePolicy: Popup.NoAutoClose)

When ever i am using closePolicy: Popup.NoAutoClose,
This popup is opened all the time and not getting closed (which is valid). When i am switching to some other screen, popup is opened and visible in other screens also.
How to avoid this kind of behaviour?
Note: I want popup to be visible specific to that particular screen where it is opened and not on other screens.
You can use Binding to control the popup's visibility based on the name of the screen it was opened in:
import QtQuick 2.12
import QtQuick.Controls 2.12
ApplicationWindow {
id: window
width: 400
height: 400
visible: true
Popup {
id: popup
width: 200
height: 200
visible: true
closePolicy: Popup.NoAutoClose
property string originalScreenName
Component.onCompleted: originalScreenName = ApplicationWindow.window.screen.name
Binding {
target: popup
property: "visible"
value: popup.ApplicationWindow.window.screen.name === popup.originalScreenName
}
}
}
I don't know if the name property can change during the lifetime of the application (e.g. due to a user renaming it), but so far it's the only way I've found of uniquely identifying a screen, as the other properties like serialNumber are not set for me, and QTBUG-85934 prevents comparing screen objects.

QML - Prevent MouseArea's positionChanged signal to propagate in ScrollView

This post is a copy of a message I already sent on the Qt forum but I couldn't get an answer.
You can find the original post here: https://forum.qt.io/topic/113890/prevent-mousearea-s-positionchanged-signal-to-propagate-in-scrollview/4
If the link is dead, everything is copied below:
I am trying to handle a positionChanged signal in a MouseArea (to create kind of a drag&drop effet) that is in a ScrollView.
My problem is that after the mouse travelled a short distance, the parent ScrollView seem's to get the focus (the scrollbar appears) and I stop to receive positionChanged signals.
The objective would be to receive the positionChanged signal (even if the mouse gets out of my MouseArea & over the ScrollView as long as my left mouse button stays pressed) without propagating the signal to the ScrollView.
I have 3 separate examples. This is a simple QML application that should be easy to run.
The two first examples work. The third does not work.
What is "working":
Press the mouse button down on the MouseArea
Move the mouse around without releasing the button
The message that logs coordinates should never stop printing, wherever you are on screen until you release the mouse button.
For the third example, I get logs until the mouse moves too much and all the updates stop.
Only ScrollView (works)
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
ApplicationWindow{
id: root
visible: true
width: 1200
height: 600
ScrollView {
clip: true
anchors.fill: parent
MouseArea {
width: 300
height: 300
onPositionChanged: {
console.log('Moved', mouseX, mouseY)
}
}
}
}
Only ColumnLayout (works)
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
ApplicationWindow{
id: root
visible: true
width: 1200
height: 600
ColumnLayout {
MouseArea {
width: 300
height: 300
onPositionChanged: {
console.log('Moved', mouseX, mouseY)
}
}
}
}
ColumnLayout inside a ScrollView (does not work)
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
ApplicationWindow {
id: root
visible: true
width: 1200
height: 600
ScrollView {
clip: true
anchors.fill: parent
// note: It does not work for ColumnLayout, Column, Row or RowLayout. If I use a Item here, it works
ColumnLayout {
MouseArea {
width: 300
height: 300
onPositionChanged: {
console.log('Moved', mouseX, mouseY)
}
}
}
}
}
You can find a video of the behavior here: https://i.imgur.com/rIlWnhu.mp4
I press and release the mouse without moving: I get the pressed & released events correctly
I press and move the mouse: I get the pressed event, the move event, then it stops. No more move or released events.
I press and move the mouse without going too far from the position where I pressed the mouse: It works until I get too far
Note: I don't get any Released or Exited event, but the containsPressed property is correctly updated (ie: when I no longer receive events, its value is false). This is the property that I use to display the "Mouse pressed" text.
Is this something I do wrong with the ScrollView/ColumnLayout combo or is this a Qt bug ?
Add this to your MouseArea in your third example:
preventStealing: true
For more info see:
https://doc.qt.io/qt-5/qml-qtquick-mousearea.html#preventStealing-prop

Qml restore minimized window

Qt 5.11.1 & Qt Creator 4.7.0, Windows 10
Create a maximized window, click the button (use showMinimized() or visibility = Window.Minimized) to minimized it.
Then click the application icon in taskbar, the window supposed to show maximized. But, it's always windowed instead of maximized.
If I click the system "minimize button" top-right corner, the window can restore to maximized.
main.qml:
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Window 2.3
Window {
visible: true
width: 640
height: 480
Component.onCompleted: showMaximized()
Button {
anchors.centerIn: parent
onClicked: {
showMinimized()
// visibility = Window.Minimized
}
}
}

Resources