我的问题很难解释,但我正在尽力而为.请在这方面帮助我.
我在QtDesigner中设计了一个GUI,并将.ui文件转换为.py例如. main_window.py.现在,为了避免在main_window.py中进行更改,我为侦听器创建了另一个类.
class Main():
window = None
app = None
def __init__(self):
self.launch()
self.attach_listener()
self.execute()
''' Launch GUI '''
def launch(self):
self.app = QtGui.QApplication(sys.argv)
self.window = Ui_MainWindow()
self.window.show()
''' Execute Window '''
def execute(self):
sys.exit(self.app.exec_())
''' Attach Listeners '''
def attach_listener(self):
self.window.add_button.clicked.connect(self.add_listener)
self.window.delete_button.clicked.connect(self.delete_listener)
self.window.update_button.clicked.connect(self.update_listener)
self.window.connect(self.window.combo_box, QtCore.SIGNAL('activated(QString)'), self.logout_listener)
我还有另一个具有相同结构的child_window.py,但是由于QApplication而无法从该窗口打开该窗口.我搜索了答案,但无法应用于我的代码.当从QtGui.QMainWindow或QtGui.QWidget扩展类时,这些答案适用.但是我的情况有所不同.
解决方法:
您正在将Ui_MainWindow对象与实际的窗口对象(QMainWindow,QDialog,QWidget等)混合在一起.self.window = Ui_MainWindow()不会执行任何操作,因为您将其附加到的类不是Window.您需要创建一个窗口并将Ui_MainWindow应用于它.
显然您可以make this work,但它看起来并不漂亮.您需要通过findChild访问窗口小部件.我能看到的唯一好处是,在设计器中更改了表单后,您无需运行pyside-uic,这很容易.
更简单的方法
当您使用pyuic / pyside-uic时,它将.ui文件转换为.py文件.
您不应该编辑.py文件,因为下次使用QtDesigner时,它们将被覆盖.您需要创建一个窗口类并将UI类应用于它.
设置新表格
>在QtDesigner中生成文件mainWinui.ui-类名MainWindow
>使用pyside-uic -o mainWinui.py mainWinui.ui进行转换.永远不会手动编辑mainWinui.py
>创建mainWinClass.py以加载ui.py并完成所有自定义UI工作
>声明信号和插槽,在mainWinClass.py中使用.connect等
其中一些模块名称可能看起来有些尴尬,但是我已经选择了它们,因为过去我在模块和类之间的名称冲突方面遇到了麻烦.由我不了解Qt Designer如何处理其命名引起的.
如果查看pyside-uic创建的文件,则其顶部包含需要在mainWinClass.py中使用的正确的类和方法名称.
mainWinui.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'mainWinui.ui'
#
# Created: Sun Feb 7 14:22:09 2016
# by: pyside-uic 0.2.15 running on PySide 1.2.4
#
# WARNING! All changes made in this file will be lost!
from PySide import QtCore, QtGui
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
创建一个新的mainwinClass.py并向其复制正确的导入和类名,再加上一些样板文件以加载.ui.
看起来像这样:
mainWinClass.py
from mainWinui import Ui_MainWindow
from PySide import QtGui
class MainWin(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.setup_signals()
# Is this is the same as your Listeners ??
def setup_signals(self):
# Signal for updating the lineedits from the grid
self.ui.tabWidget.currentChanged.connect(self.onTabChanged)
# Connect the "Add Staff" button to the addStaffMember method
self.ui.btnAddStaff.clicked.connect(self.addStaffMember)
然后使用另一个文件来启动应用程序本身,并维护应用程序的某些非GUI方面,例如更新程序或全局日志记录.
我已经看到了所有子窗口都在此处实例化的代码,但是我(通常)不这样做.我将其保留为主要形式.这取决于您打算如何设计应用程序.
appname.py
from PySide import QtGui, QtCore
from mainwinClass import MainWin
import sys
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mainWin = MainWin()
mainWin.show()
sys.exit(app.exec_())
# Nothing else _needed_ in here
现在,对于所有子窗口,请再次遵循相同的步骤.
模态形式
在Qt Designer中,创建一个新的“按钮底部的对话框”.
根据需要添加小部件并另存为dialogAddStaffui.ui.
跑
pyside-uic -o dialogAddStaffui.py dialogAddStaffui.ui.
创建一个新的空文本文档,名为dialogAddStaffClass.py,并使用
dialogAddStaffui.ui作为类名等的参考.编辑dialogAddStaffClass.py如下所示:
dialogAddStaffClass
from dialogAddStaffui import Ui_DialogAddStaff
from PySide import QtCore, QtGui
class DialogAddStaff(QtGui.QDialog):
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.ui = Ui_DialogAddStaff()
self.ui.setupUi(self)
# Your own init stuff
这两个进口是这里唯一需要的进口.
如果您要复制此文件,请意识到在Qt Designer中
windowModality = ApplicationModal,并且该表单是“带有按钮底部的对话框”
对于这些简单形式,它们具有一个accept方法,该方法检查用户输入的数据的有效性并使用self.done(1)关闭.
如果要查看如何处理验证和关闭:
dialogAddStaffClass
def validate(self):
retval = True
if not self.ui.editLname.text():
retval = False
QtGui.QMessageBox.information(self, 'Invalid Last name',
"Last Name must not be blank")
self.ui.editLname.setFocus()
return retval
def accept(self):
if self.validate():
self.done(1)
通过这些对话框,Qt会自动将“确定”按钮设置为触发接受.我只是覆盖了这种方法.
如果要在父级和子级之间进行通信,则可以在引用父级的子级上设置一个属性,也可以在其关闭后但在变量被垃圾回收之前读取该子级的属性.创建循环引用可能会有问题,因此请小心.
由于新窗体是模式窗体,因此用户必须先关闭子窗体,然后才能与主窗体进行交互,并且启动儿童窗口的功能将停止,直到关闭子窗体为止,因此可以使用本地窗体存放子类的变量.
“添加员工”按钮连接到addStaffMember函数.
mainWinClass.py
from dialogAddStaffClass import DialogAddStaff
def addStaffMember(self):
addStaffForm = DialogAddStaff()
res = addStaffForm.exec_() # exec_ waits, show would continue
# Function waits here for the Modal form to close.
if res: # child was closed with OK and validated correctly
print(addStaffForm.ui.editLname.text())
# Saveing other Staff data happens here
因为子窗体是使用exec_运行的,所以主窗体会等到子窗体关闭后再继续.当函数退出时,将对addStaffForm变量进行垃圾回收,因此不再有对子窗体属性的引用. (可能没有表格…)
如果要打开一个长期存在的表单,则可以在更持久的地方实例化它.
非模态形式
这是一个SisterForm的示例.它是在设计器中通过“主窗口”类型创建的(具有其自己的菜单和状态栏等).如果不需要这些装饰,请使用Dialog窗体,但将其windowModality设置为NonModal.
>在Qt Designer中创建sisterWinui.ui-设置objectName SisterWin
> pyside-uic -o sisterWinui.py sisterWinui.ui
>创建一个文件sisterwinClass.py-设置它的导入和初始化
>制作一个变量以将其保存在很长的地方(MainWin本身,请使用self.ref属性)
>为此创建一个启动按钮,并将其连接到MainWin类中的方法
姐姐Winui.ui
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'sisterWinui.ui'
#
# Created: Mon Feb 8 12:05:37 2016
# by: pyside-uic 0.2.15 running on PySide 1.2.4
#
# WARNING! All changes made in this file will be lost!
from PySide import QtCore, QtGui
class Ui_SisterWin(object):
def setupUi(self, SisterWin):
SisterWin.setObjectName("SisterWin")
奔跑
pyside-uic -o sisterWinui.py sisterWinui.ui
创建一个文件sisterwinClass.py-设置它的导入和初始化
sisterwinClass.py
from sisterWinui import Ui_SisterWin
from PySide import QtCore, QtGui
class SisterWin(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.ui = Ui_SisterWin()
self.ui.setupUi(self)
# Your custom stuff after this
在Qt Designer中,向您的主窗体中添加一个按钮或任何东西以启动sisterForm.然后对mainwinClass进行一些编辑.
制作变量以将其保存在长寿的地方
mainwinClass
from sisterwinClass import SisterWin
# no other new imports needed, just the stuff you had before
class MainWin(QtGui.QMainWindow):
def __init__(self, parent=None):
# These three lines were already there
QtGui.QMainWindow.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
# Add a long lived attribute to hold the class instance
self.sisterWin = None
# Next line was already there
self.setup_signals()
def setup_signals(self):
# Connect button to openSisterWin
self.ui.btnSisterwin.clicked.connect(self.openSisterWin)
# You probably have other connects after this
# This toggles the window
def openSisterWin(self):
if not self.sisterWin:
self.sisterWin = SisterWin()
if self.sisterWin.isVisible():
print('Hiding')
self.sisterWin.hide()
# hide or close, it's your choice
# self.sisterWin.close()
else:
print('Showing')
self.sisterWin.show()
我希望这能涵盖您现在正在寻找的东西吗?
如果试图找出如何隐藏主窗口,请看here
快乐黑客:-)