1

我想恢复主“main.qml”的位置和大小。但我不知道如何声明新窗口的父级。如果我直接从 javascript 中的 main.qml 窗口打开窗口,但通过 python 我看不到如何打开窗口,我没有问题。

我想我必须使用“self.win”但如何声明它?

感谢您的回复。

测试.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot
import sys

class Main2(QObject):

    def __init__(self, engine, what_send_for_send_the_parent):
        QObject.__init__(self)

        """ 
        How can I say to the new windows who is the parent  ?
        """
        context = engine.rootContext()
        context.setContextProperty("py_Page2", self)
        engine.load('test2.qml')
        self.win = engine.rootObjects()[0]  

class Main(QObject):

    def __init__(self, engine):
        QObject.__init__(self)

        self.context = engine.rootContext()
        self.property = self.context.setContextProperty("py_Page", self)
        self.load = engine.load('test.qml')
        self.win = engine.rootObjects()[0]  

        print("Context", self.context)  # <PyQt5.QtQml.QQmlContext object at 0xb65e6f30>
        print("Property", self.property)# None
        print("Load", self.property)    # None
        print("Win", self.win)          # <PyQt5.QtGui.QWindow object at 0xb65e6f80>

if __name__ == "__main__":
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()

    main = Main(engine) 
    main2 = Main2(engine, "???")

    engine.quit.connect(app.quit)
    sys.exit(app.exec_())

测试.qml

import QtQuick 2.5
import QtQuick.Controls 1.4

ApplicationWindow {
    id: "main"
    visible: true
    width: 200; height: 240;    
    Text {text: qsTr("main")} 
}

test2.qml

import QtQuick 2.5
import QtQuick.Controls 1.4

ApplicationWindow {
    id: "main2"
    visible: true
    width: 200; height: 240;
    x: main.x
    y: main.y
    Text {text: qsTr("main2")}
}

我想我找到了:

class Main2(QObject):

    def __init__(self, engine, master):
        QObject.__init__(self)
        context = engine.rootContext()
        context.setContextProperty("main_x", master.win.property("x"))
        context.setContextProperty("main_y", master.win.property("y"))
        engine.load('test2.qml')

...
    main = Main(engine) 
    main2 = Main2(engine, main)
...

在文件 qml

ApplicationWindow {
    id: "main2"
    visible: true
    width: 200; height: 240;
    x: main_x + 20
    y: main_y + 120
    Text {text: qsTr("main2")}
}

我可以恢复这样的价值。这个对吗?有没有更传统的方法?

4

1 回答 1

2

尽管该解决方案在这种情况下有效,但在更实际的情况下可能会失败,因为每个 QML 可以加载许多组件,因为 QML 加载是异步的,但您的过程是同步的。

解决方案是创建一个 QObject 并使用 setContextProperty() 将其导出到 QML,以便可以从通过 QQmlApplicationEngine 加载的所有 QML 访问它。该 QObject 必须具有一个属性,该属性是您要获取的属性的镜像。

主文件

from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject, QPoint, QUrl
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine


class Manager(QObject):
    positionChanged = pyqtSignal()

    def __init__(self, parent=None):
        super().__init__(parent)
        self._position = QPoint()

    @pyqtProperty(QPoint, notify=positionChanged)
    def position(self):
        return self._position

    @position.setter
    def position(self, p):
        if self._position != p:
            self._position = p
            self.positionChanged.emit()


if __name__ == "__main__":
    import os
    import sys

    app = QGuiApplication(sys.argv)

    engine = QQmlApplicationEngine()
    manager = Manager()
    engine.rootContext().setContextProperty("manager", manager)

    current_dir = os.path.dirname(os.path.realpath(__file__))

    engine.load(QUrl.fromLocalFile(os.path.join("test.qml")))
    engine.load(QUrl.fromLocalFile(os.path.join("test2.qml")))

    engine.quit.connect(app.quit)
    sys.exit(app.exec_())

测试.qml

import QtQuick 2.5
import QtQuick.Controls 1.4

ApplicationWindow {
    id: root
    visible: true
    width: 200
    height: 240
    Text {
        text: qsTr("main")
    }
    Component.onCompleted: manager.position = Qt.point(root.x, root.y)
}

test2.qml

import QtQuick 2.5
import QtQuick.Controls 1.4

ApplicationWindow {
    visible: true
    width: 200
    height: 240
    x: manager.position.x
    y: manager.position.x
    Text {
        text: qsTr("main2")
    }
}
于 2019-10-13T16:37:10.800 回答