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
}
}
}
}
}
Related
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
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
QSystemTrayIcon not available in application if run with sudo. How can this problem be solved?
./qsystemtrayicontest - the tray icon is available
sudo ./qsystemtrayicontest - the tray icon is not available
output
QML debugging is enabled. Only use this in a safe environment.
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
ERROR: No native SystemTrayIcon implementation available.
Qt Labs Platform requires Qt Widgets on this setup.
Add 'QT = widgets' to .pro and create QApplication in main().
qml: SystemTrayIcon::available false
Below is a minimal example with a qml interface. But on ordinary widget error is repeated in the same way.
qsystemtrayicontest.pro
QT += quick
CONFIG += c++11
QT += widgets
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
main.cpp
RESOURCES += qml.qrc
QML_IMPORT_PATH =
QML_DESIGNER_IMPORT_PATH =
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
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.12
import QtQuick.Window 2.12
import Qt.labs.platform 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Text {
anchors.centerIn: parent
text: "SystemTrayIcon::available: " + idSystemTrayIcon.available
}
SystemTrayIcon {
id: idSystemTrayIcon
visible: true
Component.onCompleted: {
console.log("SystemTrayIcon::available", available)
}
}
}
I can't use QtQuick.Controls 1.2 and QtQuick.Controls 2.12 in one program. Although in Qt 5.10 this worked. Now I get this message when I load main.qml:
"qrc:/MyButton.qml 2 module QtQuick.Controls 2.12 is not installed"
Qt 5.12. Build on macOS for ios or ios emulator.
pro file
QT += quick quickcontrols2
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
main.cpp
RESOURCES += qml.qrc
QML_IMPORT_PATH =
QML_DESIGNER_IMPORT_PATH =
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.2
Window {
visible: true
Button {
id: button1
text: "Controls 1 button"
anchors.centerIn: parent
}
MyButton {
text: "Controls 2 button"
anchors {
top: button1.bottom
horizontalCenter: parent.horizontalCenter
}
}
}
MyButton.qml
import QtQuick 2.9
import QtQuick.Controls 2.12
Button {
}
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();
}
qml.qrc
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>MyButton.qml</file>
</qresource>
</RCC>
Perhaps there are some restrictions or rules that need to be followed to make it work? If use only Constools 1.2 or only Constols 2.12, then main.qml loaded successfully.
p.s. Build on windows for windows and build on windows for android works fine. The problem is only with build on mac os for ios/ios emulator.
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 = ""
}