Qml application is not fitting when you change resolution - qt

I have a simple qml ApplicationWindow program with "Maximized" visibility. The application fits properly on my screen when the PC setting is below:
Resolution : 1920x1080 (Recommended)
Scale : 100%
screenshot : Resolution_1920x1080_scale_100_screenshot.JPG
But,when I configured the laptop’s setting “Scale and Layout” to 100% and laptop display at the highest resolution (1366 x 768), the right side of my application is being cut.
screenshot (which has issue): Resolution_1355x768_scale_100_screenshot.JPG
Any suggestions to solve it??
Qml:
import QtQuick 2.14
import QtQuick.Controls 2.14
ApplicationWindow {
id:root
visible: true
visibility: Window.Maximized//"Maximized"
title: qsTr("Hello World")
Rectangle {id:red; width: 900; height: 350; color: "red" }
Rectangle {id:yellow; width: 900; height: 350; color: "yellow"; anchors.left: red.right }
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
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();
}
Below is the screenshot of application with resolution 1920x1080 setting. Both Red and Yellow rectangles are of same size.
Above one is the screenshot of application with resolution 1366x768 setting. Both Red and Yellow rectangles are of same size. But, yellow half part is not visible with these setting.

in your code you used fixed size Rectangles. So changing the display resolution won't change the size of the items. Use relative position and size for this to work:
import QtQuick 2.14
import QtQuick.Controls 2.14
ApplicationWindow {
id:root
visible: true
visibility: Window.Maximized//"Maximized"
title: qsTr("Hello World")
Rectangle {id:red; width: root.width/2; height: parent.height; color: "red" }
Rectangle {id:yellow; width: root.width/2; height: parent.height; color: "yellow"; anchors.left: red.right }
}

Related

Reproducing OS Minimize Behaviour in a Custom Titlle Bar done in QML

I'm being tasked with creating a customized title bar for our application. It needs to have rounded corners and a settings button, amongst other things. It will run exclusively on windows.
Our application uses Qt and QML for the front end.
So the only way I could find how to do this is by making the application window frameless and creating the title bar from scratch.
This is my test code:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.0
ApplicationWindow {
id: mainWindow
visible: true
visibility: Window.Maximized
title: qsTr("Hello World")
flags: Qt.FramelessWindowHint | Qt.Window | Qt.WA_TranslucentBackground
//flags: Qt.Window | Qt.WA_TranslucentBackground
color: "#00000000"
TitleBar {
id: mainTitleBar
width: mainWindow.width;
height: mainWindow.height*0.018
color: "#aaaaaa"
onCloseApplication: {
Qt.quit();
}
onMinimizeApplication: {
mainWindow.visibility = Window.Minimized
}
}
Component.onCompleted: {
console.log("Size: " + mainWindow.width + "x" + mainWindow.height)
mainTitleBar.width = mainWindow.width
mainTitleBar.height = mainWindow.height*0.023;
}
Rectangle {
id: content
width: mainWindow.width
height: mainWindow.height - mainTitleBar.height
anchors.top: mainTitleBar.bottom
anchors.left: mainTitleBar.left
color: "#00ff00"
}
}
And
Here is the title bar code (TitleBar.js file):
import QtQuick 2.0
import QtQuick.Controls 2.0
Rectangle {
/*
* Requires setting up of
* -> width
* -> height
* -> title text
* -> icon path.
* -> Background color.
*/
id: vmWindowTitleBar
border.width: 0
x: 0
y: 0
radius: 20
signal closeApplication();
signal minimizeApplication();
// The purpose of this rectangle is to erase the bottom rounded corners
Rectangle {
width: parent.width
height: parent.height/2;
anchors.bottom: parent.bottom
anchors.left: parent.left
border.width: 0
color: parent.color
}
Text {
id: titleBarText
text: "This is The Title Bar"
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: parent.width*0.018
}
Button {
id: minimizeButton
width: height
height: vmWindowTitleBar.height*0.8
anchors.right: closeButton.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: parent.width*0.018
background: Rectangle {
id: btnMinimizeRect
color: vmWindowTitleBar.color
anchors.fill: parent
}
onPressed:{
minimizeApplication()
}
scale: pressed? 0.8:1;
contentItem: Canvas {
id: btnMinimizeCanvas
contextType: "2d"
anchors.fill: parent
onPaint: {
var ctx = btnMinimizeCanvas.getContext("2d");
var h = minimizeButton.height;
var w = minimizeButton.width;
ctx.reset();
ctx.strokeStyle = minimizeButton.pressed? "#58595b": "#757575";
ctx.lineWidth = 6;
ctx.lineCap = "round"
ctx.moveTo(0,h);
ctx.lineTo(w,h);
ctx.closePath();
ctx.stroke();
}
}
}
Button {
id: closeButton
//hoverEnabled: false
width: height
height: vmWindowTitleBar.height*0.8
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: parent.width*0.018
background: Rectangle {
id: btnCloseRect
color: vmWindowTitleBar.color
anchors.fill: parent
}
onPressed:{
closeApplication()
}
scale: pressed? 0.8:1;
Behavior on scale{
NumberAnimation {
duration: 10
}
}
contentItem: Canvas {
id: btnCloseCanvas
contextType: "2d"
anchors.fill: parent
onPaint: {
var ctx = btnCloseCanvas.getContext("2d");
var h = closeButton.height;
var w = closeButton.width;
ctx.reset();
ctx.strokeStyle = closeButton.pressed? "#58595b": "#757575";
ctx.lineWidth = 2;
ctx.lineCap = "round"
ctx.moveTo(0,0);
ctx.lineTo(w,h);
ctx.moveTo(w,0);
ctx.lineTo(0,h);
ctx.closePath();
ctx.stroke();
}
}
}
}
Now the problem comes with minimizing the application. The first thing I realize is that when using the Qt.FramelessWindowHint flag, the icon does not appear in the Windows Taskbar. Furthermore if I minimize it this happens:
And If I click on it, it doesn't restore.
So my question is, is there a way to reproduce regular minimize behavior when pressing the minimize button?
Or alternatively, is there a way I can completely customize the title bar of the application so that I can achieve the look and feel set by our UI designer?
NOTE: The current look is just a quick test. I have not set the gradient, font, or the aforementioned settings button.
As for me, playing with frameless windows and transparent background is kind of workaround. As I know, the only way to apply a custom shape to the window is QWindow::setMask. Sinse Window is derived from QWindow you can do that in this way.
For example, in the main.cpp:
QWindow *wnd = qobject_cast<QWindow *>(engine.rootObjects().at(0));
auto f = [wnd]() {
QPainterPath path;
path.addRoundedRect(QRectF(0, 0, wnd->geometry().width(), wnd->geometry().height()), 30, 30);
QRegion region(path.toFillPolygon().toPolygon());
wnd->setMask(region);
};
QObject::connect(wnd, &QWindow::widthChanged, f);
QObject::connect(wnd, &QWindow::heightChanged, f);
f();
Since you 'cut' the shape from the window itself, excluding title bar and frames you can leave the window flags as is.
Look at this way, I try to create something that you do but change completely your code.
the problem that makes change in your window size after you minimize the window is that you didn't set the initial width and height for the window so when you minimize the app it shows in the minimum width and height.
so you need to add just this in main.qml and set the initial width and height to the maximum.
width: maximumWidth
height:maximumHeight
but In the code below I change something else too.
For example, you didn't need to emit signals and then catch them in main.qml
you have access to mainWindow in TitleBar.qml.
in TitleBar.qml :
import QtQuick 2.0
import QtQuick.Controls 2.0
Rectangle {
anchors.fill: parent
height: 30
Row {
id: row
anchors.fill: parent
Label {
id: label
text: qsTr("Title ")
}
Button {
id: button
x: parent.width -80
text: qsTr("close")
onClicked:
{
mainWindow.close()
}
}
Button {
id: button1
x: parent.width -160
width: 90
text: qsTr("Minimized")
onClicked:
{
mainWindow.showMinimized()
}
}
}
}
and in main.qml :
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.0
import "."
Window {
id: mainWindow
visible: true
visibility: Window.FullScreen
title: qsTr("Hello World")
flags: Qt.FramelessWindowHint | Qt.Window | Qt.WA_TranslucentBackground
width: maximumWidth
height:maximumHeight
Rectangle {
id: content
anchors.fill: parent
x: 0
y: 20
width: mainWindow.width
height: mainWindow.height - mainTitleBar.height
anchors.top: mainTitleBar.bottom
anchors.left: mainTitleBar.left
color: "#00ff00"
}
TitleBar {
id: mainTitleBar
color: "#aaaaaa"
anchors.bottomMargin: parent.height -40
anchors.fill: parent
}
}

QML HorizontalHeaderView not working as expected

I'm trying to add a header to a TableView in QML, but it is not working as expected. Here's a sample code:
Main.cpp:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
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:
import QtQuick 2.12
import QtQuick.Window 2.12
import Qt.labs.qmlmodels 1.0
import QtQuick.Controls 2.15
Window {
width: 600
height: 600
visible: true
title: "Player"
TableView {
id: tableView
anchors.fill: parent
columnSpacing: 1
rowSpacing: 1
boundsBehavior: Flickable.StopAtBounds
model: TableModel {
id: tabela
TableModelColumn { display: "type" }
TableModelColumn { display: "speed" }
TableModelColumn { display: "ammunition" }
TableModelColumn { display: "active" }
TableModelColumn { display: "coordinates" }
rows: [
{
type: "1",
speed: "10",
ammunition: "30",
active: "True",
coordinates: "4x2"
},
{
type: "3",
speed: "0",
ammunition: "3",
active: "False",
coordinates: "10x2"
},
]
}
delegate: Text {
text: model.display
padding: 20
Rectangle {
anchors.fill: parent
color: "#efefef"
z: -1
}
}
}
HorizontalHeaderView {
id: horizontalHeader
syncView: tableView
anchors.left: tableView.left
model: TableModel {
TableModelColumn { display: "type"}
TableModelColumn { display: "speed" }
TableModelColumn { display: "ammunition" }
TableModelColumn { display: "active" }
TableModelColumn { display: "coordinates" }
}
}
}
Here's the output I get from this code:
Why is the header overlapped with the table? I've provided the header with a a sync view (tableView) in order to sync the header to table. According to the documentation:
Once this property is bound to another TableView, both header and table will synchronize with regard to column widths, column spacing, and flicking horizontally.
The header's label also seems wrong. I was expecting to get "Type", "Speed", etc. I haven't found much documentation about TableModelColumn, which is used to build the header.
You can set the topMargin property of TableView to the height of the header to keep the header row above the content rows.
TableView {
id: tableView
topMargin: horizontalHeader.implicitHeight
model: TableModel {
}
}
HorizontalHeaderView {
id: horizontalHeader
syncView: tableView
anchors.left: tableView.left
}
And syncView means the HorizontalHeaderView will use the model of the TableView, to my understanding you shouldn't need to specify the model property in the HorizontalTableView.

ApplicationWindow and header overdraw

I wonder why I get this result
As you can see, the Header is above the rectangle.
When I check everything, I got toolBar.parent === rect.parent. So the parent is common at both. Since the parent is the same, when I do anchors.top: parent.top I must not get something like anchors.top: toolBar.bottom.
Here is my full code :
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls.Material 2.12
import "EasyWidget"
ApplicationWindow {
id: mainWindow;
visible: true;
width: 480;
height: 640;
title: qsTr("Easy Music Video");
header: ApplicationToolBar {
id: toolBar;
width: mainWindow.width;
height: mainWindow.height / 8;
title: qsTr("Music");
onClicked: console.log("clicked");
}
Rectangle {
z: 1;
id:rect;
color: Material.color(Material.BlueGrey);
width: mainWindow.width / 3;
anchors {
bottom: parent.bottom;
top: parent.top;
left: parent.left;
//topMargin: -toolBar.height;
}
}
}
I must use the topMargin: -toolBar.height to solve the problem, but I wonder why I get this result since the parent are the same...
The documentation shows the layout:
https://doc.qt.io/qt-5/qml-qtquick-controls2-applicationwindow.html#details
The parent is the same, but the contentItem is positioned below the header, so anchoring rect to the top of it won't do what you want.
To fix it, add this to your Rectangle:
topMargin: -mainWindow.header.height

why setLayoutDirection doesn't work in my Qt Quick demo?

I want to set my demo layout is Right to Left, and I set this in main function, like this:
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
app.setLayoutDirection(Qt::RightToLeft)
return app.exec();
}
Here is my qml file:
import QtQuick 2.6
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
id:root
Row {
spacing: 20
Repeater {
model: 5
Rectangle {
color: "red"
opacity: (5 - index) / 5
width: 70; height: 30
Text {
text: index + 1+" hello"
width:parent.width
}
}
}
}
}
However the layout result still is left to right:
How can I get the real RTL layout, all components are right to left, include the text, just like this:
Right-to-left User Interfaces says that you should use the LayoutMirroring attached properties. Taking the example from that page:
import QtQuick 2.0
Rectangle {
LayoutMirroring.enabled: true
LayoutMirroring.childrenInherit: true
width: 300; height: 50
color: "yellow"
border.width: 1
Row {
anchors { left: parent.left; margins: 5 }
y: 5; spacing: 5
Repeater {
model: 5
Rectangle {
color: "red"
opacity: (5 - index) / 5
width: 40; height: 40
Text {
text: index + 1
anchors.centerIn: parent
}
}
}
}
}

QQuickWindow transparent

im using QQmlApplicationEngine with QQuickWindow for an application and i can't
transparent main window. i want to set a splash before application pops up and i use Window component for it and it should be transparent but it's not, my main.cpp is
int main(int argc, char *argv[])
{
Application app(argc, argv);
QShookaClient shooka_client;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("shooka", &shooka_client);
engine.load(QUrl("qrc:///shooka/shooka.qml"));
QObject *topLevel = engine.rootObjects().value(0);
QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
window->show();
window->setFlags(Qt::FramelessWindowHint);
window->setColor(Qt::transparent);
return app.exec();
}
but setColor doesn't work in win7. i know there is way for QDeclarativeView or even i found solution for QQuickview and it kinda should work for QQuickWindow but no, can anyone help me please..
One has to realize that a Window QtQuick type maps to QQuickWindow C++ class, and derives from QWindow. The window flags, per Cameron's answer, can be set. But you also need to set the opacity to, say, 0.75 to make it translucent. All of this can be done in QML, no need for setting flags from C++.
import QtQuick 2.1
import QtQuick.Controls 1.0
import QtQuick.Window 2.0
ApplicationWindow {
title: qsTr("Hello World")
width: 640
height: 480
flags: Qt.SubWindow | Qt.Tool | Qt.FramelessWindowHint | Qt.WindowSystemMenuHint | Qt.WindowStaysOnTopHint
opacity: 0.75
visible: true
menuBar: MenuBar {
Menu {
title: qsTr("File")
MenuItem {
text: qsTr("Exit")
onTriggered: Qt.quit();
}
}
}
Button {
text: "Hello World"
anchors.centerIn: parent
}
}
I know this is an old question, but as it is not marked as solved, here is my approach:
import QtQuick 2.4
import QtQuick.Controls 1.3
ApplicationWindow {
title: qsTr("Hello World")
width: 640
height: 480
flags: Qt.FramelessWindowHint
color: "transparent"
visible: true
Rectangle
{
color:"red"
width: parent.width/2
height: parent.height/2;anchors.centerIn: parent
}
}
As result, you will get a transparent background with a red rectangle in the middle. You could easily change that rectangle for an image.
Hope helped someone.
You might consider using the following code for achieving a frameless transparent window effect:
setWindowFlags(
#ifdef Q_OS_MAC
Qt::SubWindow |
#else
Qt::Tool |
#endif
Qt::FramelessWindowHint |
Qt::WindowSystemMenuHint |
Qt::WindowStaysOnTopHint
);
setAttribute(Qt::WA_NoSystemBackground, true);
// set the parent widget's background to translucent
setAttribute(Qt::WA_TranslucentBackground, true);
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
// create a display widget for displaying child widgets
QWidget* displayWidget = new QWidget;
displayWidget->setStyleSheet(".QWidget { background-color: rgba(0, 0, 0, 75%); border-width: 1px; border-style: solid; border-radius: 10px; border-color: #555555; } .QWidget:hover { background-color: rgba(68, 68, 68, 75%); border-width: 2px; border-style: solid; border-radius: 10px; border-color: #ffffff; }");
The idea is that your parent window or containing window has no frame and has a translucent background. Then you nest a child QWidget inside the parent QWidget and apply styles using QSS for transparency.

Resources