Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从UI文件连接信号_Python_Qt Designer_Pyside2 - Fatal编程技术网

Python 从UI文件连接信号

Python 从UI文件连接信号,python,qt-designer,pyside2,Python,Qt Designer,Pyside2,在几篇教程之后,我成功地整合了这个小型Python程序,它成功地拉入了一个.ui文件并在屏幕上显示: from PySide2.QtWidgets import QApplication from PySide2.QtWidgets import QDialog, QMessageBox, QVBoxLayout from PySide2.QtWidgets import QPushButton, QLineEdit from PySide2.QtCore import QFile, Slot

在几篇教程之后,我成功地整合了这个小型Python程序,它成功地拉入了一个
.ui
文件并在屏幕上显示:

from PySide2.QtWidgets import QApplication
from PySide2.QtWidgets import QDialog, QMessageBox, QVBoxLayout
from PySide2.QtWidgets import QPushButton, QLineEdit
from PySide2.QtCore import QFile, Slot
from PySide2.QtUiTools import QUiLoader

class Dialog(QDialog):
    def __init__(self, parent = None):
        super(Dialog, self).__init__(parent)
        print('hey')

    def alert(self):
        print('Alert')

if __name__ == '__main__':
    app = QApplication([])

    loader = QUiLoader()
    loader.registerCustomWidget(Dialog)

    ui_file = QFile('alert-quit.ui')
    ui_file.open(QFile.ReadOnly)
    dialog = loader.load(ui_file)
    ui_file.close()

    dialog.show()
对话框显示正确,但我得到了错误
QObject::connect:没有这样的插槽QDialog::alert()
,按钮什么也不做。(也不显示
hey
文本。)

.ui
文件包含带有“警报”按钮信号的
QDialog
的定义:

我不确定registerCustomWidget()是什么,从另一个回复来看,这似乎是应该做的事情。遗憾的是,
circle.ui
包含的内容失败了

并且没有显示如何与
.ui
文件本身中定义的项交互

如何从
.ui
文件加载完整的
QDialog
,并获取其中的按钮以触发代码中的操作

注意:由于我无法附加
.ui
文件,因此它的XML如下:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>344</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <widget class="QLineEdit" name="lineEdit"/>
   </item>
   <item>
    <widget class="QPushButton" name="alert_button">
     <property name="maximumSize">
      <size>
       <width>100</width>
       <height>16777215</height>
      </size>
     </property>
     <property name="text">
      <string>Alert</string>
     </property>
    </widget>
   </item>
   <item>
    <widget class="QPushButton" name="quit_button">
     <property name="maximumSize">
      <size>
       <width>100</width>
       <height>16777215</height>
      </size>
     </property>
     <property name="text">
      <string>Quit</string>
     </property>
    </widget>
   </item>
   <item>
    <spacer name="verticalSpacer">
     <property name="orientation">
      <enum>Qt::Vertical</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>20</width>
       <height>40</height>
      </size>
     </property>
    </spacer>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections>
  <connection>
   <sender>alert_button</sender>
   <signal>clicked()</signal>
   <receiver>Dialog</receiver>
   <slot>alert()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>91</x>
     <y>30</y>
    </hint>
    <hint type="destinationlabel">
     <x>133</x>
     <y>51</y>
    </hint>
   </hints>
  </connection>
 </connections>
 <slots>
  <slot>alert()</slot>
  <slot>quit()</slot>
 </slots>
</ui>

对话
0
0
344
300
对话
100
16777215
警觉的
100
16777215
退出
Qt::垂直
20
40
警报按钮
点击()
对话
警报()
91
30
133
51
警报()
退出

正如我在对我的问题的评论中所写,我找到了一个有效的解决方案。我不是100%确定,它是正确的(至少对于与手动编辑
.ui
文件相关的部分而言),但我得到了对话框的显示,并以我期望的方式进行操作

首先,我必须修改
.ui
文件中的XML,并在
.py
.ui
文件中使用两个不同的类名。我已将
.ui
中的一个修改为
AlertDialog
,类型为
Dialog
,而不是
QDialog
。我找不到在Qt设计器中修改类型的方法

3,4c3,4
<  <class>Dialog</class>
<  <widget class="QDialog" name="Dialog">
---
>  <class>AlertDialog</class>
>  <widget class="Dialog" name="AlertDialog">
18c18
<     <widget class="QLineEdit" name="lineEdit"/>
---
>     <widget class="QLineEdit" name="text_field"/>
66c66
<    <receiver>Dialog</receiver>
---
>    <receiver>AlertDialog</receiver>

很好,不是吗?如果任何人(我的未来自我包含…)知道如何摆脱
.ui
调整或对该解决方案有其他改进,欢迎您的意见

由于我在Pyside2上也做了很多努力,我在这里分享了我是如何做到这一点的,我不确定这是最好的方法,但它对我来说是有效的

首先,您必须使用以下设备安装
pyqt5

pip3 install pyqt5
假设您的文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>344</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <widget class="QLineEdit" name="lineEdit"/>
   </item>
   <item>
    <widget class="QPushButton" name="alert_button">
     <property name="maximumSize">
      <size>
       <width>100</width>
       <height>16777215</height>
      </size>
     </property>
     <property name="text">
      <string>Alert</string>
     </property>
    </widget>
   </item>
   <item>
    <widget class="QPushButton" name="quit_button">
     <property name="maximumSize">
      <size>
       <width>100</width>
       <height>16777215</height>
      </size>
     </property>
     <property name="text">
      <string>Quit</string>
     </property>
    </widget>
   </item>
   <item>
    <spacer name="verticalSpacer">
     <property name="orientation">
      <enum>Qt::Vertical</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>20</width>
       <height>40</height>
      </size>
     </property>
    </spacer>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections>
  <connection>
   <sender>alert_button</sender>
   <signal>clicked()</signal>
   <receiver>Dialog</receiver>
   <slot>alert()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>91</x>
     <y>30</y>
    </hint>
    <hint type="destinationlabel">
     <x>133</x>
     <y>51</y>
    </hint>
   </hints>
  </connection>
 </connections>
 <slots>
  <slot>alert()</slot>
  <slot>quit()</slot>
 </slots>
</ui>
通常有以下输出:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'test.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(344, 300)
        self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
        self.verticalLayout.setObjectName("verticalLayout")
        self.lineEdit = QtWidgets.QLineEdit(Dialog)
        self.lineEdit.setObjectName("lineEdit")
        self.verticalLayout.addWidget(self.lineEdit)
        self.alert_button = QtWidgets.QPushButton(Dialog)
        self.alert_button.setMaximumSize(QtCore.QSize(100, 16777215))
        self.alert_button.setObjectName("alert_button")
        self.verticalLayout.addWidget(self.alert_button)
        self.quit_button = QtWidgets.QPushButton(Dialog)
        self.quit_button.setMaximumSize(QtCore.QSize(100, 16777215))
        self.quit_button.setObjectName("quit_button")
        self.verticalLayout.addWidget(self.quit_button)
        spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout.addItem(spacerItem)

        self.retranslateUi(Dialog)
        self.alert_button.clicked.connect(Dialog.alert)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.alert_button.setText(_translate("Dialog", "Alert"))
        self.quit_button.setText(_translate("Dialog", "Quit"))
您只需更正导入并加载生成的文件:

from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2.QtCore import QFile, QObject 
import mainwindow  # if your generated file name is mainWindow.py

class MainDialog(QDialog, mainwindow.Ui_Dialog):

    def __init__(self, parent=None):
        super(MainDialog, self).__init__(parent)
        self.setupUi(self)

app = QApplication(sys.argv)
form = MainDialog()
form.show()
app.exec_()

好吧,我没有停止试验,而且,凭借我昨天读到的一些帖子的记忆,帮助我进入了好的轨道。很快我就能回答我自己的问题:-)不,还是不在这里。现在我可以在python类中获得链接到函数的信号,但是我仍然无法从slot函数引用对话框中的文本字段。。。有什么想法吗?你在评论中提到的问题是另一个方向的。另一方面,在PySide2中,没有执行此类任务的loadUI方法,其想法是实现此方法,该方法包括解析.ui并获取所有元素并建立连接感谢@eyllanesc我通过稍微手动调整
.ui
使其正常工作。我现在正在写我自己问题的答案,我很快就会把它贴出来。经过对
.ui
的调整,它看起来像一个干净的答案。。。但我欢迎进一步的评论和改进(最重要的是,如果我能避免
.ui
文件中的黑客攻击!)您将不得不解析该文件,这就是PyQt5所做的,我建议您查看它以便理解逻辑。我继续我的独白。虽然这个解决方案中的代码非常简洁,但是创建一个可执行文件(例如PyInstaller)变得更加棘手。现在,如果您想分发代码,您可能应该坚持使用Python代码中的
.ui
代码与
pyside uic
进行良好的转换。好吧,这里您使用的是pyqt5,而不是pyside2。。。您正在使用
uic
工具转换Python代码中的
.ui
文件。这也适用于pyisde2。正如我后来发现的,这也适用于pyside2。但我的目标不是首先转换文件…:-)“摆脱.ui调整”这部分答案让我很困惑,但我明白了你的意思,谢谢你,我不知道pyside2well的uic工具的存在,想法是摆脱.ui调整并保持.ui文件的动态加载:-)
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'test.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(344, 300)
        self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
        self.verticalLayout.setObjectName("verticalLayout")
        self.lineEdit = QtWidgets.QLineEdit(Dialog)
        self.lineEdit.setObjectName("lineEdit")
        self.verticalLayout.addWidget(self.lineEdit)
        self.alert_button = QtWidgets.QPushButton(Dialog)
        self.alert_button.setMaximumSize(QtCore.QSize(100, 16777215))
        self.alert_button.setObjectName("alert_button")
        self.verticalLayout.addWidget(self.alert_button)
        self.quit_button = QtWidgets.QPushButton(Dialog)
        self.quit_button.setMaximumSize(QtCore.QSize(100, 16777215))
        self.quit_button.setObjectName("quit_button")
        self.verticalLayout.addWidget(self.quit_button)
        spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout.addItem(spacerItem)

        self.retranslateUi(Dialog)
        self.alert_button.clicked.connect(Dialog.alert)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.alert_button.setText(_translate("Dialog", "Alert"))
        self.quit_button.setText(_translate("Dialog", "Quit"))
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2.QtCore import QFile, QObject 
import mainwindow  # if your generated file name is mainWindow.py

class MainDialog(QDialog, mainwindow.Ui_Dialog):

    def __init__(self, parent=None):
        super(MainDialog, self).__init__(parent)
        self.setupUi(self)

app = QApplication(sys.argv)
form = MainDialog()
form.show()
app.exec_()