QtQuick GeometryChanged方法仅对加载的零部件在一个方向上有效

2024-10-01 02:18:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在构建一个Python+QtQuick应用程序,它需要一个从QQuickPaintedItem降序的类。我在管理上漆物品的布局和尺寸时遇到了一些问题。你知道吗

特别是,我有这样的应用程序

enter image description here

左边有一组按钮,窗口的右边是一个Loader(这是一个很好的理由,这只是一个演示问题的最小示例)。你知道吗

主qml文件(main.qml)如下所示:

import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3

ApplicationWindow {
    id: mainWindow
    visible: true
    width: 720
    height: 480
    title: qsTr("QML Sampler")
    onClosing: main.close_application()

    RowLayout {
        anchors.fill: parent

        ColumnLayout {
            id: sideBar
            Layout.fillHeight: true
            Layout.preferredWidth: 200
            Layout.minimumWidth: 150
            Layout.maximumWidth: 350

            Button {
                id: buttonScreen1
                text: "Button 1"
                Layout.fillWidth: true
            }

            Button {
                id: buttonScreen2
                text: "Button 2"
                Layout.fillWidth: true
            }
        }

        Loader {
            id: contentAreaLoader
            Layout.fillHeight: true
            Layout.preferredWidth: 520
            Layout.minimumWidth: 300

            source: 'loaded_content.qml'
        }
    }
}

加载的内容文件实际上包含自定义类,如下所示(loaded_content.qml):

import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3

import CustomPaintedItem 1.0

ColumnLayout {
    anchors.fill: parent

    Label {
        text: "Here's a thing!"
    }

    CustomPaintedItem {
        Layout.fillHeight: true
        Layout.fillWidth: true
    }
}

调整窗口大小时,我希望能够获得QQuickPaintedItem的新维度,因此在代码中,我重写了QQuickPaintedItem.geometryChanged()方法。在这个例子中,我只是简单地打印新的和旧的几何图形。你知道吗

下面是所有这些的剩余代码。涉及到三个python文件,一个用于main,一个用于CustomPaintedItem类,一个用于主控制器。你知道吗

main.py看起来像这样:

import os
import sys

from PyQt5.QtQml import QQmlApplicationEngine, qmlRegisterType
from PyQt5.QtWidgets import QApplication

from main_controller import MainController
from custom_painted_item import CustomPaintedItem


def main():
    print('main()')

    qmlRegisterType(CustomPaintedItem, "CustomPaintedItem", 1, 0, "CustomPaintedItem")

    app = QApplication(sys.argv)
    engine = QQmlApplicationEngine()
    main_controller = MainController()
    context = engine.rootContext()
    context.setContextProperty("main", main_controller)
    script_directory = os.path.dirname(os.path.abspath(__file__))
    engine.load(os.path.join(script_directory, 'main.qml'))

    main_controller.start()

    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

控制器main_controller.py如下所示:

from PyQt5.QtCore import QObject, pyqtSlot


class MainController(QObject):
    def __init__(self):
        super().__init__()
        print('ctor')

    def start(self):
        print('start')

    @pyqtSlot()
    def close_application(self):
        print('close')

最后,custom_painted_item.py

from PyQt5.QtQuick import QQuickPaintedItem
from PyQt5.QtCore import QTimer


class CustomPaintedItem(QQuickPaintedItem):
    def __init__(self, parent=None):
        super().__init__(parent=parent)
        QTimer.singleShot(100, self.update)

    def paint(self, QPainter):
        QTimer.singleShot(100, self.update)

    def geometryChanged(self, old_geom, new_geom):
        print('OLD: {0} x {1}'.format(old_geom.width(), old_geom.height()))
        print('NEW: {0} x {1}'.format(new_geom.width(), new_geom.height()))

运行此代码时,我可以调整窗口在y维度上的大小(使其变高或变短),并看到高度按预期变化:

OLD: 520.0 x 455.0
NEW: 520.0 x 454.0
OLD: 520.0 x 454.0
NEW: 520.0 x 453.0

但是,当我在x维中调整窗口的大小(使其更宽或更窄)时,报告的宽度从初始值520(窗口宽度720减去首选侧边栏宽度200)一直不变。事实上,当我调整宽度时,geometryChanged()方法甚至从未被调用。你知道吗

如果注释掉Loader组件,并直接用ColumnLayout组件替换它,如下所示:

//        Loader {
//            id: contentAreaLoader
//            Layout.fillHeight: true
//            Layout.preferredWidth: 520
//            Layout.minimumWidth: 300

//            source: 'loaded_content.qml'
//        }

        ColumnLayout {
            Layout.fillHeight: true
            Layout.preferredWidth: 520
            Layout.minimumWidth: 300

            Label {
                text: "Here's a thing!"
            }

            CustomPaintedItem {
                Layout.fillHeight: true
                Layout.fillWidth: true
            }
        }

然后正确调用geometryChanged()方法来调整x和y的大小。我不知道这是一个错误,一些我不了解的加载程序,或一些关于布局。你知道吗

如果有关系的话,我使用的是python3.6和pyqt5.11.3。你知道吗

有谁能给我一些关于如何使装载机工作的见解吗?谢谢!你知道吗


Tags: fromimportselfidtruemaindefqml
1条回答
网友
1楼 · 发布于 2024-10-01 02:18:52

在不使用加载程序的情况下,布局只处理子级:ColumnLayout占用可用空间,因为maximumWidth已经建立,因此它将是无限的(所有可以等价于Layout.fillWidth: true)。另一方面,不是布局的加载程序没有该大小策略,因此如果希望它占用所有可用空间,则必须显式使用Layout.fillWidth: true。你知道吗

Loader {
    id: contentAreaLoader
    Layout.fillHeight: true
    Layout.preferredWidth: 520
    Layout.minimumWidth: 300
    Layout.fillWidth: true // <  
    source: 'loaded_content.qml'
}

相关问题 更多 >