Simple button click connection to python function

丶灬走出姿态 提交于 2020-06-23 13:06:09

问题


I have a very simple Qml/Python application with some content in a StackView(), with the first page containing a simple button. My question is, does EVERYTHING between Qml and Python work via signals only? Or can the button click fire/call a function directly from a python script?

Haven't tried much, as I am not sure how to proceed from here

main.qml

import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.5
import "custom/components"


ApplicationWindow {
    visible: true
    width: 800
    height: 600
    minimumWidth: 800
    minimumHeight: 600

    title: qsTr('Primer')

    property bool authorized: false

    signal change_page(bool change)


    // Main Container - View
    StackView {
        id: view
        anchors.fill: parent
        initialItem: home
    }


    // Page Content
    Component {
        id: home
        Page {
            title: qsTr('Home')

            GenButton {
                text: "To Orders"
                bg_color: "white"
                txt_color: "grey"

                onClicked: homeFunc.changePage()
            }
        }
    }

    Component {
        id: orders
        Page {
            title: qsTr('Orders')
        }
    }

    Component {
        id: quotes
        Page {
            title: qsTr('Quotes')
        }
    }

}

GenButton.qml

import QtQuick 2.12
import QtQuick.Controls 2.5


Button {
    id: ctrl

    property color bg_color: "white"
    property color txt_color: "black"

    background: Rectangle {
        color: ctrl.pressed ? Qt.darker(bg_color, 1.25) : bg_color
    }

    contentItem: Text {
        text: ctrl.text
        padding: ctrl.padding
        horizontalAlignment: Text.AlignHCenter
        verticalAlignment: Text.AlignVCenter
        font.family: "Segoe UI"
        font.pixelSize: 14
        color: txt_color
    }
}

main.py

import sys
from PyQt5.QtGui import QGuiApplication, QIcon
from PyQt5.QtQml import QQmlApplicationEngine
from resources.functions.homeFunctions import HomeFunctions


APP = QGuiApplication(sys.argv)
APP.setWindowIcon(QIcon('resources/img/primerLogo.png'))

home_func = HomeFunctions()

ENGINE = QQmlApplicationEngine()
ENGINE.rootContext().setContextProperty('homeFunc', home_func)
ENGINE.load('resources/qml/main.qml')
ENGINE.quit.connect(APP.quit)

sys.exit(APP.exec_())

homeFunctions.py

from PyQt5.QtCore import QObject


class HomeFunctions(QObject):
    def __init__(self):
        QObject.__init__(self)


    def changePage(self):
        print("Button was pressed")

Expected result would be for the terminal to print the message "Button was pressed", a very simple example, which could probably have been achieved a 1000 different other ways, but this is merely just a test

The error received is the following:

file:///D:/Personal Backups/CodingProjects/PycharmProjects/calico/resources/qml/main.qml:40: TypeError: Property 'changePage' of object HomeFunctions(0xc3f5c8) is not a function

回答1:


Explanation:

QML uses the MetaObject (MOC) of the QObjects to access the properties, signals and slots, in your case changePage is not a slot but a function that is not accessible from QML.

Solution:

The solution is to make the changePage function accessible in QML using the @pyqtSlot decorator:

homeFunctions.py

from PyQt5.QtCore import pyqtSlot, QObject


class HomeFunctions(QObject):
    @pyqtSlot()
    def changePage(self):
        print("Button was pressed")


来源:https://stackoverflow.com/questions/58487558/simple-button-click-connection-to-python-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!