PyQt5中直接导入.ui文件使用自定义Widget的问题
如何直接加载Qt Creator的.ui自定义Widget无需pyuic转换?
当然可以直接用uic.loadUi()跳过pyuic转.py的步骤,完全没问题!你遇到的错误是主窗口里的frame已经自带布局了,重复设置布局才触发了报错。
为什么会报错?
错误提示QWidget::setLayout: Attempting to set QLayout "" on QFrame "frame", which already has a layout很明确——你的main.ui文件里,frame控件已经被Qt Creator默认添加了一个布局。这时候你再手动调用setLayout()给它套新布局,就会产生冲突。
修正后的代码
下面给你两种可行的解决方式,选适合你的就行:
方式1:复用frame已有的布局(推荐)
如果main.ui里的frame本来就有布局(比如你在Qt Creator里给它加了QVBoxLayout),直接拿这个布局添加自定义Widget就行:
import sys from PyQt5 import QtWidgets, uic class mainGUIWindow(QtWidgets.QMainWindow): def __init__(self): super().__init__() # 直接加载主窗口UI到当前实例 uic.loadUi('main.ui', self) # 创建自定义Widget并加载它的UI self.my_widget = myWidget() # 获取frame自带的布局,把自定义Widget加进去 self.frame.layout().addWidget(self.my_widget) class myWidget(QtWidgets.QWidget): def __init__(self): super().__init__() # 直接加载自定义Widget的.ui文件,一步到位 uic.loadUi('MyWidget.ui', self) if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) window = mainGUIWindow() window.show() sys.exit(app.exec_())
方式2:替换frame的原有布局
如果你确实需要给frame换个新布局,得先把旧布局清理掉再设置新的:
import sys from PyQt5 import QtWidgets, uic class mainGUIWindow(QtWidgets.QMainWindow): def __init__(self): super().__init__() uic.loadUi('main.ui', self) # 先移除frame的旧布局(如果存在) if self.frame.layout() is not None: old_layout = self.frame.layout() # 清空布局里的所有控件 while old_layout.count(): item = old_layout.takeAt(0) if item.widget(): item.widget().deleteLater() del old_layout # 创建新布局,把自定义Widget加进去 self.my_widget = myWidget() hbox_layout = QtWidgets.QHBoxLayout(self.frame) hbox_layout.addWidget(self.my_widget) class myWidget(QtWidgets.QWidget): def __init__(self): super().__init__() uic.loadUi('MyWidget.ui', self) if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) window = mainGUIWindow() window.show() sys.exit(app.exec_())
小技巧补充
- 用
uic.loadUi(ui_file_path, self)的时候,UI里的所有控件会直接成为当前类的属性,比如你在MyWidget.ui里有个按钮叫pushButton,那在myWidget类里直接用self.pushButton就能访问,非常方便。 - 这种直接加载.ui的方式,修改Qt Creator里的UI后,不用再跑pyuic命令,重启Python程序就能看到变化,开发效率提升不少~
内容的提问来源于stack exchange,提问作者Gwendal Grelier
相关产品推荐
相关产品推荐

