Accept/reject signals of dialog not catched - qt

Upgrading Qt to v5.10.1 the Dialog doesn't emit accept/reject signals. The last known version that works smooth was 5.10.0. My question is - does I miss something or I use some component in wrong way? Or it is regression (and I will report it?)
Issue reproduced on macOS 10.12+ & Win10 (VC 2015/2017)
Simplified source code sample:
CMakeLists.txt
cmake_minimum_required(VERSION 3.11)
project(bug-test LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt5 COMPONENTS Core Quick REQUIRED)
add_executable(${PROJECT_NAME} "main.cpp" "qml.qrc")
target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Quick)
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty()) return -1;
return app.exec();
}
main.qml
import QtQuick 2.9
import QtQuick.Controls 2.2
ApplicationWindow {
id: applicationWindow
visible: true
Button {
text: qsTr("Push me!")
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
onClicked: dlgLoader.source = "qrc:/MsgDialog.qml"
}
Loader {
id: dlgLoader
onStatusChanged: {
if (dlgLoader.status == Loader.Ready) {
item.parent = ApplicationWindow.overlay
item.open()
}
}
}
Connections {
target: dlgLoader.item
onClosed: dlgLoader.source = ""
}
}
MsgDialog.qml
import QtQuick 2.9
MsgDialogForm {
x: (parent.width - width) / 2
y: (parent.height - height) / 2
width: Math.min(applicationWindow.width, applicationWindow.height) / 5 * 4
onAccepted: console.log("Ok clicked; save answer")
onRejected: console.log("Cancel clicked; don't save")
}
MsgDialogForm.ui.qml
import QtQuick 2.9
import QtQuick.Controls 2.3
Dialog {
id: dialog
modal: true
standardButtons: Dialog.Yes | Dialog.No
closePolicy: Popup.CloseOnEscape
}
qml.qrc
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>qtquickcontrols2.conf</file>
<file>MsgDialog.qml</file>
<file>MsgDialogForm.ui.qml</file>
</qresource>
</RCC>
Just start the app; push the button and click one of dialog buttons. Nothing is shown in QtCreator console but dialog is closed.

When a new item is established in the Loader the previous item is deleted from the memory, in your case you are doing it when the window is closed, but the accepted or rejected signal is emited after the window is closed.
A possible solution is to create a signal that is emited after receiving the message.
MsgDialog.qml
import QtQuick 2.9
MsgDialogForm {
signal finished()
x: (parent.width - width) / 2
y: (parent.height - height) / 2
width: Math.min(applicationWindow.width, applicationWindow.height) / 5 * 4
onAccepted: {
console.log("Ok clicked; save answer")
finished()
}
onRejected: {
console.log("Cancel clicked; don't save")
finished()
}
}
main.qml
...
Connections {
target: dlgLoader.item
onFinished: dlgLoader.source = ""
}

Related

Qt Virtual Keyboard in QQuickWidget

It is possible to show Virtual Keyboard in QQuickWidget or in QWidget?
I have QWidget application and I need to have better control where VirtualKeyboard is shown.
Today I spend all my day to find a solution, unfortunately without success.
The following code shows that it is valid to use virtualkeyboard in QQuickWidget.
main.cpp
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQuickWidget>
int main(int argc, char *argv[])
{
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
QQuickWidget widget;
widget.setResizeMode(QQuickWidget::SizeRootObjectToView);
widget.setSource(QStringLiteral("qrc:/main.qml"));
widget.show();
return app.exec();
}
main.qml
import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.VirtualKeyboard 2.14
Rectangle {
id: window
width: 640
height: 480
TextEdit{
text: "Hello world"
anchors.centerIn: parent
}
InputPanel {
id: inputPanel
z: 99
x: 0
y: window.height
width: window.width
states: State {
name: "visible"
when: inputPanel.active
PropertyChanges {
target: inputPanel
y: window.height - inputPanel.height
}
}
transitions: Transition {
from: ""
to: "visible"
reversible: true
ParallelAnimation {
NumberAnimation {
properties: "y"
duration: 250
easing.type: Easing.InOutQuad
}
}
}
}
}
qml.qrc
<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
</RCC>
59777221.pro
QT += quickwidgets virtualkeyboard
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp
RESOURCES += qml.qrc
├── 59777221.pro
├── main.cpp
├── main.qml
└── qml.qrc

Issue with Material Style in QML

I have this small example that does not work as i expected :
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.2
Window {
id: root
visible: true
width: 640
height: 480
property bool lightTheme: false
Material.theme: Material.Dark
Material.foreground: Material.color(Material.Red) // value is always material red #F44336 (from light theme)
onLightThemeChanged: {
Material.theme = lightTheme ? Material.Light : Material.Dark;
}
Button {
id: btn
width: 200
height: 200
anchors.centerIn: parent
text: "change theme"
onClicked: {
lightTheme = !lightTheme;
}
}
Text {
id: darkRed
text: "predefinedDarkThemeRed"
color: "#EF9A9A"
anchors.top: btn.bottom
anchors.horizontalCenter: btn.horizontalCenter
}
Text {
id: lightRed
text: "predefinedLightThemeRed"
color: "#F44336"
anchors.top: darkRed.bottom
anchors.left: darkRed.left
}
}
The issue is with the default Material.Red color being always picked from the Material.Light theme whatever theme i have selected.
However, when i don't set any Material.foreground, then it is white with the Material.Dark and dark with the Material.Light, and dynamically switched between those colors when the theme is changed, so everything is fine.
I would expected the same behaviour with a custom Material.foreground but it does not seem to work.
What is wrong here ?
Thank you.
Note: the app is run with options -style material args, and i am using Qt 5.9.3 or Qt 5.10.1
i think you missed a little nuance
add in .pro file
QT += quickcontrols2
in mine file add QQuickStyle::setStyle("Material");
#include <QQuickStyle>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
................
QQuickStyle::setStyle("Material");
//The style can also be specified as a path to a custom style, such as
//QQuickStyle::setStyle(":/mystyle");
................
return app.exec();
}
in your example, the result will be
when pressed

Cmake: accessing qtvirtual keyboard module

Can anyone do a simple example of including qtvirtualkeyboard module into a cmake file? I want to access the classes but I cannot figure out how to include it.
Qt's virtual keyboard is just another module, it can be loaded with find_package. The minimal example of cmake file being:
cmake_minimum_required(VERSION 3.5.0 FATAL_ERROR)
PROJECT("MyKeyboard")
set(CMAKE_PREFIX_PATH $ENV{QTDIR})
find_package(Qt5 COMPONENTS Widgets VirtualKeyboard REQUIRED)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
add_executable("MyKeyboard"
main.cpp
)
target_link_libraries("MyKeyboard" Qt5::Widgets Qt5::VirtualKeyboard)
This example should work. It was compiled using CMake 3.1.1 and Qt 5.11.1
The code is available in my GitHub account. The QML example is based on the example provided by Qt.
Main CMakeLists.txt
cmake_minimum_required(VERSION 3.1)
# 3rd party tools
find_package(Qt5 COMPONENTS Widgets Qml Quick REQUIRED)
# Directory with the source code
add_subdirectory(src)
CMakeLists.txt included in the subdirectory
include_directories(${Qt5Widgets_INCLUDE_DIRS} ${QtQml_INCLUDE_DIRS})
add_definitions(${Qt5Widgets_DEFINITIONS} ${QtQml_DEFINITIONS} ${${Qt5Quick_DEFINITIONS}})
qt5_add_resources(QT_RESOURCES qml.qrc)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(PROJECT "virtualkeyboard-cmake-56202469")
project(${PROJECT})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++11 -fstrict-aliasing -pedantic-errors -pedantic -Wno-deprecated-declarations -Wno-unused-variable")
if(NOT DEFINED HEADERS)
file(GLOB HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)
endif()
if(NOT DEFINED SOURCES)
file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
endif()
source_group("Header Files" FILES ${HEADERS})
source_group("Source Files" FILES ${SOURCES})
add_executable(${PROJECT} ${HEADERS} ${SOURCES} ${QT_RESOURCES})
target_link_libraries(${PROJECT}
Qt5::Widgets
Qt5::Qml
Qt5::Quick
)
qml.qrc
<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
</RCC>
main.cpp
#include <QQuickView>
#include <QGuiApplication>
#include <QQmlEngine>
int main(int argc, char** argv)
{
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QGuiApplication app(argc, argv);
QQuickView view(QString("qrc:/main.qml"));
if (view.status() == QQuickView::Error)
return -1;
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.show();
return app.exec();
}
main.qml
import QtQuick 2.10
import QtQuick.Controls 2.3
import QtQuick.VirtualKeyboard 2.1
Rectangle {
width: 1280
height: 720
color: "#F6F6F6"
Flickable {
id: flickable
anchors.fill: parent
contentWidth: content.width
contentHeight: content.height
interactive: contentHeight > height
flickableDirection: Flickable.VerticalFlick
property real scrollMarginVertical: 20
MouseArea {
id: content
width: flickable.width
height: textEditors.height + 24
onClicked: focus = true
Column {
id: textEditors
spacing: 15
x: 12
y: 12
width: parent.width - 26
Label {
color: "#565758"
text: "Tap fields to enter text"
anchors.horizontalCenter: parent.horizontalCenter
font.pixelSize: 22
}
TextField {
width: parent.width
placeholderText: "One line field"
onAccepted: passwordField.focus = true
}
TextField {
id: passwordField
width: parent.width
echoMode: TextInput.Password
placeholderText: "Password field"
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhPreferLowercase | Qt.ImhSensitiveData | Qt.ImhNoPredictiveText
onAccepted: upperCaseField.focus = true
}
}
}
}
}

QtQuick StackView loading issues

I'm working through the book "Learn Qt 5" from Nicholas Sherriff.
Now I have some problems getting the QtStackView component to work properly.
I've written following code:
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/views/MasterView.qml")));
return app.exec();
}
MasterView.qml
import QtQuick 2.5
import QtQuick.Window 2.0
import QtQuick.Controls 1.4
Window {
visible: true
width: 1024
height: 768
title: qsTr("Client Management")
StackView {
id: contentFrame
initialItem: Qt.resolvedUrl("qrc:/views/SplashView.qml")
}
}
SplashView.qml
import QtQuick 2.5
Rectangle {
anchors.fill: parent
color: "#f04c42"
}
But when executing, the rectangle from SplashView.qml does not appear.
I do not get any errors. If I put the rectangle block inside the window block it works. But even if i put the rectangle with an id in the StackView block it doesn't work.
I'm using an older version of QtQuick than the book recommends, becouse im using not the newest debian distribution.
Am I missing something?
Thanks
The problem is simple, the Rectangle in the SplashView takes the size of the parent:
Rectangle {
anchors.fill: parent //<---
color: "#f04c42"
}
And the parent is the StackView, but the StackView has no size, so the solution is to set a size, for this we can use the anchors:
StackView {
id: contentFrame
anchors.fill: parent // <--- possible solution
initialItem: Qt.resolvedUrl("qrc:/views/SplashView.qml")
}

How to get signal key pressed on QT virtual keyboard and play a sound click track?

in my QT application for embedded device , i want play a sound on key pressed event of the QML virtualkeyboard . Can I get this event? and How get it?
I already have a class that play sound ( click effect) when a button was clicked that i use in the others qml pages
import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3
import QtQuick.VirtualKeyboard 2.1
Page{
id: pag
width: 1280
height: 800
background: Rectangle { color: "black"}
TextField {
id: txtName
height: 200
width:200
anchors.horizontalcenter:parent.horizontalCenter
font.family: "Arial
font.pixelSize: 24
placeholderText: "insert your text here"
background: Rectangle {
anchors.fill: parent
color: "transparent"
}
}
InputPanel {
id: virtualkeyboard
width: 0.95*parent.width
anchors.bottom: parent.bottom
}
}
You can create a class Mykeyfilter, it's a QObject class
then in your file .h you declare:
bool eventFilter(QObject *object, QEvent *event);
Then in your Mykeyfilter.cpp file you define eventFilter like this:
bool MykeyFilter::eventFilter(QObject *object, QEvent *event)
{
switch(event->type())
{
case QEvent::KeyPress:
case QEvent::KeyRelease:
{
//////call your sound class here that you want to play/////
qDebug()<<"I have clicked" //For testing
}
default:
break;
// return QObject::eventFilter(object, event);
}
return QObject::eventFilter(object, event);
}
Also add in your main.cpp file:
#include "mytouchfilter.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
app.installEventFilter(new MykeyFilter());
return app.exec();
}
You have two options:
Use the clicked() signal of BaseKey.
Use the soundEffect property of KeyPanel.
Both require having your own style. You can read more about creating your own style here. To quote from there:
A good starting point for creating a new style is to use an existing built-in style as a template and edit it. You can find the built-in styles from the virtual keyboard sources directory src/virtualkeyboard/content/styles. Copy one of the directories containing a built-in style into the Styles directory and rename it to "test". [...]

Resources