I am working on a desktop environment and I want my QML window as my main desktop window. I am integrating QML with PyQt5.
here is my code
import sys from PyQt5 import* from PyQt5.QtCore import* from PyQt5.QtWidgets import* from PyQt5.QtQuick import* from PyQt5.QtQml import* from threading import Thread import os import importlib import subprocess import tempfile import re import random import os.path from os import path dir_path = os.path.dirname(os.path.realpath(__file__)) if __name__ == '__main__': myApp = QApplication(sys.argv) engine = QQmlApplicationEngine() context = engine.rootContext() context.setContextProperty("main", engine) engine.load('/home/newtron/Muscovy/main.qml') window = QMainWindow() win = engine.rootObjects()[0] win.show() window.setAttribute(Qt.WA_X11NetWmWindowTypeDesktop, True) sys.exit(myApp.exec_())
main.qml
import QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 2.12 ApplicationWindow { property var theme: String("#ffffff") property var focusColor: String('transparent') id: applicationWindow visible: true width: Screen.width height: Screen.height color: "#2d2b2b" title: qsTr("Muscovy") background: Image { id: image anchors.fill: parent source: "../Pictures/Wallpapers/113844.jpg" fillMode: Image.PreserveAspectCrop } PropertyAnimation{ id: themeOpen target: rectangle duration: 200 property: 'anchors.rightMargin' to: 0 } PropertyAnimation{ id: themeClose target: rectangle duration: 200 property: 'anchors.rightMargin' to: -45 } Loader { id: loader anchors.fill: parent source: 'main2.qml' } Rectangle { id: rectangle x: 1166 y: 391 width: 50 height: 225 color: "#68ffffff" radius: 25 anchors.right: parent.right anchors.rightMargin: -45 anchors.verticalCenter: parent.verticalCenter MouseArea { id: mouseArea anchors.fill: parent hoverEnabled: true onEntered: { themeOpen.start() } onExited: { themeClose.start() } } RoundButton { id: roundButton1 x: 7 y: 142 anchors.top: parent.top anchors.topMargin: 142 anchors.right: parent.right anchors.rightMargin: 7 anchors.left: parent.left anchors.leftMargin: 7 anchors.bottom: parent.bottom anchors.bottomMargin: 48 onClicked:{ theme = String('#ffffff') loader.source = 'main2.qml' } background: Rectangle { id: rectan1 height: 20 color: "#434343" radius: parent.radius gradient: Gradient { GradientStop { position: 0.00; color: "#00f7ff"; } GradientStop { position: 1.00; color: "#0091ff"; } } anchors.fill: parent rotation: 45 } Text { id: element1 x: 5 y: 8 color: "#ffffff" text: qsTr("Li") anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter font.pixelSize: 12 } } RoundButton { id: roundButton x: 8 y: 51 anchors.top: parent.top anchors.topMargin: 51 anchors.bottom: parent.bottom anchors.bottomMargin: 139 anchors.left: parent.left anchors.leftMargin: 8 anchors.right: parent.right anchors.rightMargin: 8 onClicked:{ theme = String('#000000') loader.source = 'main2.qml' } background: Rectangle{ id:rectan height: 20 rotation:45 color: "#434343" anchors.fill: parent radius: parent.radius gradient: Gradient { GradientStop { position: 0 color: "#434343" } GradientStop { position: 1 color: "#000000" } } } Text { id: element x: 5 y: 8 color: "#ffffff" text: qsTr("Da") anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter font.pixelSize: 12 } } } }
main2.qml
import QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 2.12 Item { DropArea{ anchors.fill: parent GridView{ id: grid anchors.fill: parent clip: true interactive: false model: listContent cellHeight:90 cellWidth:90 delegate: Component{ Rectangle { id:rectID width: 80 height: 80 color: "#002f99f6" radius: 5 border.color: "#2f99f6" border.width: 0 MouseArea { property var focused: false property var childX: parent.x/90 property var childY: parent.y/90 signal toggled drag.target: rectID onToggled: { if(focused == true){ parent.color = "#4f2f99f6" parent.border.width = 1 focused = false } else{ parent.color = "transparent" parent.border.width = 0 } } objectName: objName signal doubClicked anchors.fill: parent hoverEnabled: true Component.onCompleted: { grid.clipChanged.connect(toggled) } onEntered: { if(focused != true){ parent.color = "#4cffffff" textID.elide = Text.ElideNone textID.wrapMode = Text.WrapAnywhere parent.z = 10000 } } onExited:{ if(focused != true){ parent.color = "transparent" textID.elide = Text.ElideRight textID.wrapMode = Text.NoWrap parent.z = 5 } } onClicked: { focused = true if(grid.clip == true) grid.clip = false else grid.clip = true } onReleased: { console.log(childX.toFixed(0)) console.log(childY.toFixed(0)) parent.x = childX.toFixed(0)*90 parent.y = childY.toFixed(0)*90 } onDoubleClicked: { doubClicked() } Image { x: 8 y: 0 width: 64 height: 64 source: imgSource anchors.top: parent.top anchors.topMargin: 0 anchors.horizontalCenter: parent.horizontalCenter } Text { id:textID x: 8 y: 47 color: theme text: fileName fontSizeMode: Text.FixedSize verticalAlignment: Text.AlignTop font.weight: Font.Normal style: Text.Normal elide: Text.ElideRight wrapMode: Text.NoWrap horizontalAlignment: Text.AlignHCenter textFormat: Text.AutoText anchors.left: parent.left anchors.leftMargin: 0 anchors.right: parent.right anchors.rightMargin: 0 anchors.top: parent.top anchors.topMargin: 78 font.pixelSize: 12 clip: true } } } } } ListModel{ ListElement{ objName:"objectanyname"; fileName:"anyname"; imgSource:"unknown.png"; textID:"text11";rectID:"rect1"} ListElement{ objName:"objectany.py"; fileName:"any.py"; imgSource:"unknown.png"; textID:"text12";rectID:"rect2"} ListElement{ objName:"objectanyt.py"; fileName:"anyt.py"; imgSource:"unknown.png"; textID:"text13";rectID:"rect3"} ListElement{ objName:"objectbash"; fileName:"bash"; imgSource:"unknown.png"; textID:"text14";rectID:"rect4"} ListElement{ objName:"objectbash.py"; fileName:"bash.py"; imgSource:"unknown.png"; textID:"text15";rectID:"rect5"} ListElement{ objName:"objectbash.sh"; fileName:"bash.sh"; imgSource:"unknown.png"; textID:"text16";rectID:"rect6"} ListElement{ objName:"objectBecalm.desktop"; fileName:"Becalm.desktop"; imgSource:"unknown.png"; textID:"text17";rectID:"rect7"} ListElement{ objName:"objectbuild-datetime-Desktop_Qt_5_12_5_GCC_64bit-Debug"; fileName:"build-datetime-Desktop_Qt_5_12_5_GCC_64bit-Debug"; imgSource:"folder.png"; textID:"text18";rectID:"rect8"} ListElement{ objName:"objectcnspec.desktop"; fileName:"cnspec.desktop"; imgSource:"unknown.png"; textID:"text19";rectID:"rect9"} ListElement{ objName:"objectCounter-Strike_Global_Offensive.desktop"; fileName:"Counter-Strike Global Offensive.desktop"; imgSource:"unknown.png"; textID:"text110";rectID:"rect10"} ListElement{ objName:"objecteFootball_PES_2020.desktop"; fileName:"eFootball PES 2020.desktop"; imgSource:"unknown.png"; textID:"text111";rectID:"rect11"} ListElement{ objName:"objectfirstprogramme"; fileName:"firstprogramme"; imgSource:"folder.png"; textID:"text112";rectID:"rect12"} ListElement{ objName:"objectHimno.desktop"; fileName:"Himno.desktop"; imgSource:"unknown.png"; textID:"text113";rectID:"rect13"} ListElement{ objName:"objectmain.py"; fileName:"main.py"; imgSource:"unknown.png"; textID:"text114";rectID:"rect14"} ListElement{ objName:"objectname.py"; fileName:"name.py"; imgSource:"unknown.png"; textID:"text115";rectID:"rect15"} ListElement{ objName:"objectNUCLEAR"; fileName:"NUCLEAR"; imgSource:"folder.png"; textID:"text116";rectID:"rect16"} ListElement{ objName:"object__pycache__"; fileName:"__pycache__"; imgSource:"folder.png"; textID:"text117";rectID:"rect17"} ListElement{ objName:"objectS.A.I.A.'s_Awakening_A_Robothorium_Visual_Novel.desktop"; fileName:"S.A.I.A.'s Awakening A Robothorium Visual Novel.desktop"; imgSource:"unknown.png"; textID:"text118";rectID:"rect18"} ListElement{ objName:"objectsemi2.odp"; fileName:"semi2.odp"; imgSource:"unknown.png"; textID:"text119";rectID:"rect19"} ListElement{ objName:"objectSeminar2.pptx"; fileName:"Seminar2.pptx"; imgSource:"unknown.png"; textID:"text120";rectID:"rect20"} ListElement{ objName:"objectsemi.odp"; fileName:"semi.odp"; imgSource:"unknown.png"; textID:"text121";rectID:"rect21"} ListElement{ objName:"objectsemi.pptx"; fileName:"semi.pptx"; imgSource:"unknown.png"; textID:"text122";rectID:"rect22"} ListElement{ objName:"objectStar_Conflict.desktop"; fileName:"Star Conflict.desktop"; imgSource:"unknown.png"; textID:"text123";rectID:"rect23"} ListElement{ objName:"objectsteam.desktop"; fileName:"steam.desktop"; imgSource:"unknown.png"; textID:"text124";rectID:"rect24"} ListElement{ objName:"objecttest.py"; fileName:"test.py"; imgSource:"unknown.png"; textID:"text125";rectID:"rect25"} ListElement{ objName:"objectUntitled.png"; fileName:"Untitled.png"; imgSource:"unknown.png"; textID:"text126";rectID:"rect26"} ListElement{ objName:"objectUntitled.xcf"; fileName:"Untitled.xcf"; imgSource:"unknown.png"; textID:"text127";rectID:"rect27"} ListElement{ objName:"objectWarplanes_WW1_Sky_Aces.desktop"; fileName:"Warplanes WW1 Sky Aces.desktop"; imgSource:"unknown.png"; textID:"text128";rectID:"rect28"} ListElement{ objName:"objectZombie_Grinder_Dedicated_Server.desktop"; fileName:"Zombie Grinder Dedicated Server.desktop"; imgSource:"unknown.png"; textID:"text129";rectID:"rect29"} id:listContent } } }
I tried adding window.setAttribute(Qt.WA_X11NetWmWindowTypeDesktop, True)
in code but it doesn’t work. Also I tried adding Qt.Desktop flag also this doesn’t work. At the first time, it gave me error AttributeError: ‘QQuickWindow’ object has no attribute ‘setAttribute’. In second attempt the script ran successfully but window didn’t open. I thought it may be because another desktop window is running. So I loggend into an another console with my user name, created a bash file to run window manager and dektop window, then start it by startx /home/newtron/myscript. It opened a blank window. There wasn’t even mouse(may be a failure).
can anybody help me?
thanks.
Advertisement
Answer
Qt::WA_X11NetWmWindowTypeDesktop
is a Qt::WidgetAttribute
so it only makes sense for the QWidget and it seems that the OP understands it because in its attempt it uses a QMainWindow but the problem is that the QMainWindow does not show the QML so that is not the solution.
The idea is to have a QWidget where the QML is so in this case there are 2 possible solutions:
Set
visible: false
in ApplicationWindow and useQWidget::createWindowContainer()
:import os import sys from PyQt5.QtCore import Qt, QUrl from PyQt5.QtWidgets import QApplication, QWidget from PyQt5.QtQml import QQmlApplicationEngine DIR_PATH = os.path.dirname(os.path.realpath(__file__)) if __name__ == "__main__": myApp = QApplication(sys.argv) file = os.path.join(DIR_PATH, "main.qml") url = QUrl.fromLocalFile(file) engine = QQmlApplicationEngine() context = engine.rootContext() context.setContextProperty("main", engine) engine.load(url) if not engine.rootObjects(): sys.exit(-1) widget = QWidget.createWindowContainer(engine.rootObjects()[0]) widget.setAttribute(Qt.WA_X11NetWmWindowTypeDesktop, True) widget.showFullScreen() sys.exit(myApp.exec_())
main.qml
// ... ApplicationWindow { property var theme: String("#ffffff") property var focusColor: String('transparent') id: applicationWindow visible: false width: Screen.width // ...
QQuickView
withQWidget::createWindowContainer()
:import os import sys from PyQt5.QtCore import Qt, QUrl from PyQt5.QtWidgets import QApplication, QWidget from PyQt5.QtQuick import QQuickView DIR_PATH = os.path.dirname(os.path.realpath(__file__)) if __name__ == "__main__": myApp = QApplication(sys.argv) file = os.path.join(DIR_PATH, "main.qml") url = QUrl.fromLocalFile(file) view = QQuickView() def on_statusChanged(status): if status == QQuickView.Error: for error in view.errors(): print(error.toString()) sys.exit(-1) view.statusChanged.connect(on_statusChanged) view.setResizeMode(QQuickView.SizeRootObjectToView) engine = view.engine() context = engine.rootContext() context.setContextProperty("main", engine) view.setSource(url) view.setTitle(view.tr("Muscovy")) widget = QWidget.createWindowContainer(view) widget.setAttribute(Qt.WA_X11NetWmWindowTypeDesktop, True) widget.showMaximized() sys.exit(myApp.exec_())
main.qml
import QtQuick 2.12 import QtQuick.Controls 2.12 Rectangle { property var theme: String("#ffffff") property var focusColor: String('transparent') color: "#2d2b2b" Image { id: image anchors.fill: parent source: "../Pictures/Wallpapers/113844.jpg" fillMode: Image.PreserveAspectCrop } PropertyAnimation{ id: themeOpen target: rectangle // ...
-
import os import sys from PyQt5.QtCore import Qt, QUrl from PyQt5.QtWidgets import QApplication, QWidget from PyQt5.QtQuickWidgets import QQuickWidget DIR_PATH = os.path.dirname(os.path.realpath(__file__)) if __name__ == "__main__": myApp = QApplication(sys.argv) file = os.path.join(DIR_PATH, "main.qml") url = QUrl.fromLocalFile(file) widget = QQuickWidget() widget.resize(640, 480) def on_statusChanged(status): if status == QQuickWidget.Error: for error in view.errors(): print(error.toString()) sys.exit(-1) widget.statusChanged.connect(on_statusChanged) widget.setResizeMode(QQuickWidget.SizeRootObjectToView) engine = widget.engine() context = engine.rootContext() context.setContextProperty("main", engine) widget.setSource(url) widget.setWindowTitle(widget.tr("Muscovy")) widget.setAttribute(Qt.WA_X11NetWmWindowTypeDesktop, True) widget.showMaximized() sys.exit(myApp.exec_())
main.qml
import QtQuick 2.12 import QtQuick.Controls 2.12 Rectangle { property var theme: String("#ffffff") property var focusColor: String('transparent') color: "#2d2b2b" Image { id: image anchors.fill: parent source: "../Pictures/Wallpapers/113844.jpg" fillMode: Image.PreserveAspectCrop } PropertyAnimation{ id: themeOpen target: rectangle // ...