Popup item loses opaquness - qt

I have a weird problem with Popup QML component from QtQuick2 , when I do open() it, it shows with transparent background , and it should be opaque.
This is how I call the Popup component from the main.qml file :
NewUser {
id: new_user_form
}
This is the component's source:
// File: NewUser.qml
Popup {
id: new_user_popup
modal: true
focus: true
x: 10
y: 10
width: 300
height: 200
Rectangle {
anchors.fill: parent
color: "transparent"
border.color: "red"
}
}
And this is the output:
Now, I can fix this error by moving the source of the NewUser.qml into main.qml and everything looks fine now:
This is the now 'fixed' main.qml:
Popup {
id: new_user_form
modal: true
focus: true
x: 10
y: 10
width: 300
height: 200
}
See, the popup is completely OPAQUE:
So, why if I move the source code of the component into a separate file from main.qml it loses the opaquness ? My main.qml has a lot of other stuff, but I believe it is not related to the popup, also the ID is unique. I hope this is not some issue with QT 5.8 RC (which I am using for development) , it is not yet official but soon it will be.
EDIT:
I believe I found a bug. The bug is reproducible with Qt 5.8 and Qt 5.7
To reproduce, create a project with the following files:
Main file:
//main.qml
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
NewUser {
id: new_user_form
}
Button {
text: "open popup"
onClicked: {
new_user_form.open()
}
}
}
The component file (NewUser.qml)
//File: NewUser.qml
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Controls.Material 2.0
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.3
import Qt.labs.settings 1.0
import QtQuick.Templates 2.0
Popup {
id: new_user_popup
modal: true
focus: true
x: 10; y:10;
height: 200; width: 300;
Button {
text: "Test button"
}
}
//File: qtquickcontrols2.conf
; This file can be edited to change the style of the application
; See Styling Qt Quick Controls 2 in the documentation for details:
; http://doc.qt.io/qt-5/qtquickcontrols2-styles.html
[Controls]
Style=Material
[Universal]
Theme=Light
;Accent=Steel
[Material]
Theme=Light
;Accent=BlueGrey
;Primary=BlueGray
//File: 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(QLatin1String("qrc:/main.qml")));
return app.exec();
}
That does the bug do? If you click on the button "open popup" you will see a dimmed screen but no popup at all.

This is not a bug. See, you are not using a namespace for the templates import.
import QtQuick.Templates 2.0 as T
For the sake of clarity, there is a one-to-one mapping between the types provided by the QtQuick.Templates and QtQuick.Controls imports. For every type available in the QtQuick.Controls import, a non-visual template type by the same name exists in the QtQuick.Templates import. It is recommended to use a namespace for the templates import to avoid overlap with the types provided by the QtQuick.Controls import.

Related

how to get the tumbler to 'base style'

I am creating a simple tumbler with QML. When I run the application, the tumbler is in the "Flat Style". How to I change it to the "Base Style" (the 3D Look)?
You can see the "3D Look" at this page:
https://doc.qt.io/qt-5/qtquickcontrolsstyles-index.html
Near the top, right under Styles, Base Style
I tried setting the Style in qtquickcontrols2.conf, where I added:
[Controls]
Style=Base
This is my source code:
import QtQuick 2.13
import QtQuick.Window 2.12
import QtQuick.Controls 2.5
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Tumbler {
id: tumbler
x: 290
y: 140
model: 10
}
}
I get a working Tumbler in a Flat Style. I have no idea where to tell Qt that I want the 'Base Style' (i.e., the '3D Look').
Note: I have tried to import various versions of QtQuick.Controls 1.x (and of 2.x), but they all result in a Flat Style or an error.
Thank you.
The problem is that you are trying to apply a style of Qt Quick Controls 1 to an item of Qt Quick Controls 2. So the solution is to use the appropriate item and avoid mixing elements from different packages, and set the style using QT_QUICK_CONTROLS_1_STYLE.
main.qml
import QtQuick 2.13
import QtQuick.Window 2.12
import QtQuick.Extras 1.4 as QQE
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
QQE.Tumbler { // https://doc.qt.io/qt-5/qml-qtquick-extras-tumbler.html
id: tumbler
x: 290
y: 140
QQE.TumblerColumn {
model: 10
}
}
}
main.cpp
#include <QtGui>
#include <QtQml>
int main(int argc, char *argv[]) {
qputenv("QT_QUICK_CONTROLS_1_STYLE", "Base");
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
qml.qrc
<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
</RCC>
I thought it may be useful to note here that I found an alternative solution that I ended up using. It was just somewhat different that what I asked (if I better explained what I was trying to do, I think it would have been suggested). Since I think it may be useful for others who are in a similar situation in the future, I figured I should post it.
First, I worked through creating the tumbler per the code above, then learned how to customize it with TumblerStyle. After that, I found a good post explaining some of the logic on how QtQuickControls 1 evolved into QtQuickControls2 here.
At that point, I figured I could just customize the QtQuickControl2 Tumbler. In the end, I put the Tumbler inside a Rectangle, and added the 3D effect to the Rectangle via a Gradient.
Then my original code became:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls.Material 2.12
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle {
anchors.centerIn: parent
height: Math.round(parent.height/2)
width: Math.round(parent.width/5)
antialiasing: true;
Tumbler {
id: tumbler
anchors.fill: parent
model: 10
}
gradient: Gradient {
GradientStop { position: 0.0; color: Material.color(Material.Grey,Material.Shade500) }
GradientStop { position: 0.5; color: "transparent" }
GradientStop { position: 1.0; color: Material.color(Material.Grey,Material.Shade500) }
}
}
}
I realize that I lost the border and shadow? effects that were automatically provided by the QtQuickControl 1 Tumbler. However, I already had a border in my project, so I was only missing the shadow...and that's on my to-do list for the next release...
Lastly, I know the text size and other details need to be customized (as they are on my project); this Tumbler looks a bit awkward. I figured that the customizing, styling & adjustments don't belong in this article.

QML Calendar not showing week day or month year (however it does seem to be there....)

I am using Qt 5.13 and in general Qt.Controls 2 however the calendar only exists in v1.0 or the labs version (which I can't get to work, so using V1).
My code is
import QtQuick 2.2
import QtQuick.Controls 1.4 as Old
import Tree 1.0
import "."
ApplicationWindow {
id: window
width: 800; height: 1000
title: "TreeView Example"
visible: true
Old.Calendar {
anchors.centerIn: parent
id: calendar
}
}
However when I do this, I don't see the day of the week, nor the month/year in the navivagation bar, although I can see where they should be:
I have tried to add a navigationBar delegate, but this then gets rid of the navigation arrows.
style: CalendarStyle {
navigationBar: Text {
text: "hello"
}
}
So, how do I have the nav arrows, show the month/year and show the days of week? The documentation seems to suggest I would get these out of the box...
Now... I thought I could add drop downs as a work around to choose month/year and place them in the nav bar... however when I do that I can actually see that the days of the week are there, just their text colour is white, so I feel I am missing a trick with regard to the navigation bar...?
Worth reading the comments in response to #Aleph0's post, but to get it working I had to copy the default styles and place them within my element. The final code (stripping out the bits that aren't specifically about the calendar then), looks like
import QtQuick.Controls 2.4
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.3
import QtQuick 2.2
import QtQuick.Controls 1.4 as Old
import QtQuick.Controls.Styles 1.4
import QtQuick.Controls.Private 1.0
ApplicationWindow {
id: window
width: 300; height: 300
title: "Calendar Example"
visible: true
ColumnLayout {
anchors.fill: parent
Old.Calendar {
id: calendar
style: CalendarStyle {
gridVisible: true
dayOfWeekDelegate: Rectangle {
color: gridVisible ? "#fcfcfc" : "transparent"
implicitHeight: Math.round(TextSingleton.implicitHeight * 2.25)
Label {
text: control.locale.dayName(styleData.dayOfWeek, control.dayOfWeekFormat)
anchors.centerIn: parent
}
}
navigationBar: Rectangle {
height: Math.round(TextSingleton.implicitHeight * 2.73)
color: "#f9f9f9"
Rectangle {
color: Qt.rgba(1,1,1,0.6)
height: 1
width: parent.width
}
Rectangle {
anchors.bottom: parent.bottom
height: 1
width: parent.width
color: "#ddd"
}
HoverButton {
id: previousMonth
width: parent.height
height: width
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
source: "./assets/leftanglearrow.png"
onClicked: control.showPreviousMonth()
}
Label {
id: dateText
text: styleData.title
elide: Text.ElideRight
horizontalAlignment: Text.AlignHCenter
font.pixelSize: TextSingleton.implicitHeight * 1.25
anchors.verticalCenter: parent.verticalCenter
anchors.left: previousMonth.right
anchors.leftMargin: 2
anchors.right: nextMonth.left
anchors.rightMargin: 2
}
HoverButton {
id: nextMonth
width: parent.height
height: width
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
source: "./assets/rightanglearrow.png"
onClicked: control.showNextMonth()
}
}
}
}
}
}
That results in
In an ideal world, there would be an alternative to a) using Private controls as that seems like I am using Qt internal modules, but thats an easy fix by using an Image with a mouse area, and if I didn't have to use any 1.x controls either, but there doesn't seem to be a 2.x way of graphically displaying dates etc. Anyway, hopefully this can be useful to someone - it's literally a copy paste job of the default styling so it can be simplified alot...
I'm also using Qt 5.13.0 and just tried you example. After removing some imports it was working with the following files:
main.qml
import QtQuick 2.2
import QtQuick.Controls 1.4 as Old
import QtQuick.Controls 2.12
ApplicationWindow {
id: window
width: 800; height: 1000
title: "TreeView Example"
visible: true
Old.Calendar {
anchors.centerIn: parent
id: calendar
}
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
QQmlContext* context = engine.rootContext();
engine.load(QUrl("./data/main.qml"));
return app.exec();
}
I'll obtain the following:
I suggest, that you will try my code and compare it with your application.
I had the same problem - days of week and title were almost invisible, because they were written with white color on light gray background. In my case the problem was in desktop color theme in Ubuntu Studio. After I changed it from Dark to Light the text appeared in black as expected. It seems Qt5 can't handle dark themes well or implementation in Ubuntu Studio (22.04) is buggy. The same was true for text in Button-s.

Show message dialog

Is it possible to display a QML dialog when the user hits a button in a QML window?
Example:
When the user clicks in the menu bar on Help -> About the About dialog should be displayed:
import QtQuick 2.12
import QtQuick.Layouts 1.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import "components"
ApplicationWindow {
id: window
visible: true
width: 1040
height: 480
aboutDlg: aboutDialog {} // does not work...
menuBar: MenuBar {
Menu {
title: qsTr("Help")
MenuItem {
text: qsTr("About")
onTriggered: aboutDlg.open();
}
}
...
components/AboutDialog.qml
import QtQuick 2.2
import QtQuick.Dialogs 1.1
MessageDialog {
id: aboutDialog
title: "May I have your attention please"
text: "It's so cool that you are using Qt Quick."
onAccepted: {
console.log("And of course you could only agree.")
Qt.quit()
}
}
When I remove the line boutDlg: aboutDialog {} // does not work... the following error is reported when clicking on the About menu item:
qrc:/main.qml:61: ReferenceError: aboutDlg is not defined
How can I achieve this?
You called "aboutDialog" which is an ID in the AboutDialog.
Think of it like you add an object, like adding a Rectangle...which has its own file...and you can "instantiate" it by adding an object like so:
...
ApplicationWindow {
...
AboutDialog {
id: aboutDlg
}
...
}
You can find example HERE
You might also optimize a bit and put the AboutDialog in a Loader.

How to create some independent windows in QML

I want to create a start window like in Wolfram Mathematica, where the user can create/open file, after this window get hidden, and the program create a new window with the file editor, after closing the editor, the editor window get closed and the program show again the start window. How to make some independent windows in QML?
Since you want to have them static, and independent, it might be one idea to create multiple windows from C++.
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QUrl("./main_0.qml")));
engine.load(QUrl(QUrl("./main_1.qml")));
if (engine.rootObjects().isEmpty()) {
qDebug() << "crap";
}
return app.exec();
}
Then use any kind of common data model (e.g. context properties, singletons ...) to set them visible.
you can do something like this:
Start.qml
import QtQuick 2.11
import QtQuick.Window 2.11
Window {
visible: true
width: 640
height: 480
title: qsTr("Start Window")
onClosing: {
var component = Qt.createComponent("qrc:/Editor.qml");
component.createObject();
}
}
Editor.qml
import QtQuick 2.11
import QtQuick.Window 2.11
Window {
visible: true
width: 640
height: 480
title: qsTr("Editor")
onClosing: {
var component = Qt.createComponent("qrc:/Start.qml");
component.createObject();
}
}
Closing one view will make the other view appear. So you probably should add another button for the case that the user wants to completely quit the application.
If you want your views to be created only once, you can ignore the close event and set the visibility instead. You can for example do something like this:
Start.qml
import QtQuick 2.11
import QtQuick.Window 2.11
Window {
id: mainStartView
visible: true
width: 640
height: 480
title: qsTr("Start Window")
property var editorView
Component.onCompleted: {
editorView = editorComponent.createObject(mainStartView);
}
onClosing: {
close.accepted = false
editorView.visible = true
mainStartView.visible = false
}
Component {
id: editorComponent
Editor {
visible: false
}
}
}
Editor.qml
import QtQuick 2.11
import QtQuick.Window 2.11
Window {
width: 640
height: 480
title: qsTr("Editor")
onClosing: {
close.accepted = false
mainStartView.visible = true
visible = false
}
}

Qt Expected Character ')' Error

I am getting the following error:
Debugging starts QML debugging is enabled. Only use this in a safe
environment. QML Debugger: Waiting for connection on port 55186...
QQmlApplicationEngine failed to load component qrc:/main.qml:23
Expected token `)'
Line 23
QFile, file("C://new.txt");
The Code
#include <QIODevice>
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtQml 2.2
ApplicationWindow {
title: qsTr("File Editor")
width: 640
height: 480
visible: true
menuBar: MenuBar {
Menu {
title: qsTr("&File")
MenuItem {
text: qsTr("&Open")
onTriggered: {
var message = ("Hello World!");
QFile, file("C://new.txt");
file.open(QIODevice::ReadWrite);
QTextStream out(&file);
out << %message%;
}
}
MenuItem {
text: qsTr("E&xit")
onTriggered: Qt.quit();
}
}
}
MainForm {
anchors.fill: parent
button1.onClicked: messageDialog.show(qsTr("Button 1 pressed"))
button2.onClicked: messageDialog.show(qsTr("Button 2 pressed"))
button3.onClicked: messageDialog.show(qsTr("Button 3 pressed"))
}
MessageDialog {
id: messageDialog
title: qsTr("May I have your attention, please?")
function show(caption) {
messageDialog.text = caption;
messageDialog.open();
}
}
}
As stated by Simon Warta and BaCaRoZzo in the comments, you cannot use C++ in QML. You need to use Javascript and create your own custom type for handling file input and output.
Please see this answer.

Resources