带有命名参数的 PySide2 (5.14.2) 信号

Posted

技术标签:

【中文标题】带有命名参数的 PySide2 (5.14.2) 信号【英文标题】:PySide2 (5.14.2) signal with named parameter 【发布时间】:2020-04-03 12:20:54 【问题描述】:

PySide Signal argument can't be retrieved from QML

根据这篇文章,PySide2(版本 > 5.12.5)支持带有命名参数的信号,如 PyQt5。所以我在 PySide2 (5.14.2) 中尝试了这里并得到了类似的错误

file:///E:/​​QML/projects/main.qml:72:5:无法分配给不存在的属性“onSpitInput”

告诉我这里出了什么问题。

*app.py

import os
import sys
from PySide2 import QtCore, QtGui, QtWidgets, QtQml

class controller(QtCore.QObject):
    spitInput = QtCore.Signal(str, arguments=['userinput'])

    def __init__(self):
        QtCore.QObject.__init__(self)

    @QtCore.Slot(int, result=list)
    def getUserInput(self, first):
        self.spitInput.emit(str(first) + 'is the value given by user')


controller = controller()
app = QtWidgets.QApplication(sys.argv)
current_dir = os.path.dirname(os.path.realpath(__file__))
engine = QtQml.QQmlApplicationEngine()
engine.addImportPath(current_dir)
engine.rootContext().setContextProperty("controller", controller)
filename = os.path.join(current_dir, "main.qml")
engine.load(QtCore.QUrl.fromLocalFile(filename))

if not engine.rootObjects():
    sys.exit(-1)
engine.quit.connect(app.quit)
sys.exit(app.exec_())

main.qml

 import QtQuick 2.13
 import QtQuick.Controls 2.13

 ApplicationWindow 
  id: root
  visible: true
  width: 640
  height: 480
  title: qsTr("Hello World")

  Rectangle 
      id: bufferRectId
      width: 640
      height: 480
      anchors.fill: parent

      TextField
          id:firstTextInputFieldId
          font.pointSize: 16
          anchors.top: parent.top
          anchors.left: parent.left
          anchors.topMargin: 10
          anchors.horizontalCenter: parent.horizontalCenter
      

      Button
          id:calcButtonId
          width: 60
          height: 30
          text: "Click Me"
          anchors.horizontalCenter: parent.horizontalCenter
          anchors.top: parent.top
          anchors.topMargin: 60

          onClicked: 
              controller.getUserInput(firstTextInputFieldId.text)
          
      
  

  onSpitInput: console.log(userinput)
 

【问题讨论】:

【参考方案1】:

当您使用以下代码时:

ApplicationWindow 
   id: root
   // ...
   onSpitInput: console.log(userinput)

您说 onSpitInput 属于“root”,这显然是错误的,因为它属于“控制器”,因此失败。

在这种情况下你应该使用Connections:

import QtQuick 2.13
import QtQuick.Controls 2.13

ApplicationWindow 
    id: root
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    Rectangle 
        id: bufferRectId
        anchors.fill: parent
        TextField
            id:firstTextInputFieldId
            font.pointSize: 16
            anchors.top: parent.top
            anchors.left: parent.left
            anchors.topMargin: 10
            anchors.horizontalCenter: parent.horizontalCenter
        
        Button
            id:calcButtonId
            width: 60
            height: 30
            text: "Click Me"
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.top: parent.top
            anchors.topMargin: 60
            onClicked: controller.getUserInput(firstTextInputFieldId.text)
        
    
    Connections
        target: controller
        onSpitInput: console.log(userinput)
    

另一方面,还有另一个错误:getUserInput 方法接收一个字符串并且不返回任何内容,但根据您的代码,它必须接收一个整数并返回一个列表。正确的是:

import os
import sys

from PySide2 import QtCore, QtGui, QtWidgets, QtQml


class controller(QtCore.QObject):
    spitInput = QtCore.Signal(str, arguments=["userinput"])

    @QtCore.Slot(str)
    def getUserInput(self, first):
        self.spitInput.emit(" is the value given by user".format(first))


if __name__ == "__main__":

    controller = controller()
    app = QtWidgets.QApplication(sys.argv)
    current_dir = os.path.dirname(os.path.realpath(__file__))
    engine = QtQml.QQmlApplicationEngine()
    engine.addImportPath(current_dir)
    engine.rootContext().setContextProperty("controller", controller)
    filename = os.path.join(current_dir, "main.qml")
    engine.load(QtCore.QUrl.fromLocalFile(filename))

    if not engine.rootObjects():
        sys.exit(-1)
    engine.quit.connect(app.quit)
    sys.exit(app.exec_())

【讨论】:

以上是关于带有命名参数的 PySide2 (5.14.2) 信号的主要内容,如果未能解决你的问题,请参考以下文章

带有 Pyside2 和 Matplotlib 的 Pyinstaller 无法正常工作

带有 Pyinstaller 的 PySide2:无法执行脚本 pyi_rth_pkgres

带有 PySide2 的文件浏览器:获取文件的路径,然后终止 GUI

PySide2 使用 QProgressBar 作为信号参数

PySide2.QtWidgets.QxxxxLayout.addWidget 用错误的参数类型调用

当 slot 函数具有默认参数=None 时,PySide2 的行为与 PySide 不同