从主 window 中的 UI 文件加载具有信号槽定义的小部件
Load widget with signal-slot defintions from UI file in main window
我无法将 Qt Designer 生成的小部件加载到我的主窗口中。当我还在 UI 文件中定义信号和槽时,它失败了。
# -*- coding: utf-8 -*-
import sys
from PyQt5 import QtWidgets
from PyQt5 import uic as pyuic
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, *args):
super().__init__(*args)
self.uifile = 'serialTandemGUI.ui'
self.form_widget = pyuic.loadUi(self.uifile)
_widget = QtWidgets.QWidget()
_layout = QtWidgets.QVBoxLayout(_widget)
_layout.addWidget(self.form_widget)
self.setCentralWidget(_widget)
if __name__ == '__main__':
app = QtWidgets.QApplication.instance()
if app is None:
app = QtWidgets.QApplication(sys.argv)
app.aboutToQuit.connect(app.deleteLater)
w = MainWindow()
w.show()
app.exec_()
我得到的错误是:
AttributeError: 'QWidget' object has no attribute 'init'
是否可以通过这种方式继承小部件?蒂亚!
编辑:
这是一个简单的 UI 文件,其中包含用于演示的 clicked() 信号。只要没有定义信号,它就可以工作(即实际上只是 UI,但这只是工作的一半,甚至更少)。
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>GroupBox</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>pushButton</sender>
<signal>clicked()</signal>
<receiver>Form</receiver>
<slot>init()</slot>
<hints>
<hint type="sourcelabel">
<x>203</x>
<y>162</y>
</hint>
<hint type="destinationlabel">
<x>396</x>
<y>201</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>init()</slot>
</slots>
</ui>
解释:
当您创建 .ui 时,您只是指出点击信号与小部件的 init
方法之间存在联系,但是当您使用 loadUi()
并且不要将它作为第二个参数传递,QWidget 将使用设计的基础 class,在您的 QWidget 案例中,它显然没有 "init" 方法向您抛出该错误。
解法:
你必须创建一个class继承自QWidget并具有init
方法,然后使用loadUi()
填写它。
# -*- coding: utf-8 -*-
import os
import sys
from PyQt5 import QtCore, QtWidgets, uic as pyuic
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
current_dir = os.path.dirname(os.path.realpath(__file__))
uifile = os.path.join(current_dir, "serialTandemGUI.ui")
pyuic.loadUi(uifile, self)
@QtCore.pyqtSlot()
def init(self):
print("init")
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.form_widget = Widget()
_widget = QtWidgets.QWidget()
_layout = QtWidgets.QVBoxLayout(_widget)
_layout.addWidget(self.form_widget)
self.setCentralWidget(_widget)
if __name__ == "__main__":
app = QtWidgets.QApplication.instance() or QtWidgets.QApplication(sys.argv)
app.aboutToQuit.connect(app.deleteLater)
w = MainWindow()
w.show()
sys.exit(app.exec_())
我无法将 Qt Designer 生成的小部件加载到我的主窗口中。当我还在 UI 文件中定义信号和槽时,它失败了。
# -*- coding: utf-8 -*-
import sys
from PyQt5 import QtWidgets
from PyQt5 import uic as pyuic
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, *args):
super().__init__(*args)
self.uifile = 'serialTandemGUI.ui'
self.form_widget = pyuic.loadUi(self.uifile)
_widget = QtWidgets.QWidget()
_layout = QtWidgets.QVBoxLayout(_widget)
_layout.addWidget(self.form_widget)
self.setCentralWidget(_widget)
if __name__ == '__main__':
app = QtWidgets.QApplication.instance()
if app is None:
app = QtWidgets.QApplication(sys.argv)
app.aboutToQuit.connect(app.deleteLater)
w = MainWindow()
w.show()
app.exec_()
我得到的错误是:
AttributeError: 'QWidget' object has no attribute 'init'
是否可以通过这种方式继承小部件?蒂亚!
编辑: 这是一个简单的 UI 文件,其中包含用于演示的 clicked() 信号。只要没有定义信号,它就可以工作(即实际上只是 UI,但这只是工作的一半,甚至更少)。
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>GroupBox</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>pushButton</sender>
<signal>clicked()</signal>
<receiver>Form</receiver>
<slot>init()</slot>
<hints>
<hint type="sourcelabel">
<x>203</x>
<y>162</y>
</hint>
<hint type="destinationlabel">
<x>396</x>
<y>201</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>init()</slot>
</slots>
</ui>
解释:
当您创建 .ui 时,您只是指出点击信号与小部件的 init
方法之间存在联系,但是当您使用 loadUi()
并且不要将它作为第二个参数传递,QWidget 将使用设计的基础 class,在您的 QWidget 案例中,它显然没有 "init" 方法向您抛出该错误。
解法:
你必须创建一个class继承自QWidget并具有init
方法,然后使用loadUi()
填写它。
# -*- coding: utf-8 -*-
import os
import sys
from PyQt5 import QtCore, QtWidgets, uic as pyuic
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
current_dir = os.path.dirname(os.path.realpath(__file__))
uifile = os.path.join(current_dir, "serialTandemGUI.ui")
pyuic.loadUi(uifile, self)
@QtCore.pyqtSlot()
def init(self):
print("init")
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.form_widget = Widget()
_widget = QtWidgets.QWidget()
_layout = QtWidgets.QVBoxLayout(_widget)
_layout.addWidget(self.form_widget)
self.setCentralWidget(_widget)
if __name__ == "__main__":
app = QtWidgets.QApplication.instance() or QtWidgets.QApplication(sys.argv)
app.aboutToQuit.connect(app.deleteLater)
w = MainWindow()
w.show()
sys.exit(app.exec_())