简体   繁体   English

在PyQt中打开第二个窗口

[英]Open a second window in PyQt

I'm trying to use pyqt to show a custom QDialog window when a button on a QMainWindow is clicked. 我正在尝试使用pyqt在单击QMainWindow上的按钮时显示自定义QDialog窗口。 I keep getting the following error: 我一直收到以下错误:

$ python main.py 
DEBUG: Launch edit window
Traceback (most recent call last):
  File "/home/james/Dropbox/Database/qt/ui_med.py", line 23, in launchEditWindow
    dialog = Ui_Dialog(c)
  File "/home/james/Dropbox/Database/qt/ui_edit.py", line 15, in __init__
    QtGui.QDialog.__init__(self)
TypeError: descriptor '__init__' requires a 'sip.simplewrapper' object but received a 'Ui_Dialog'

I've gone over several online tutorials, but most of them stop just short of showing how to use a non built-in dialog window. 我已经浏览了几个在线教程,但大多数都停止展示如何使用非内置对话框窗口。 I generated the code for both the main window and the dialog using pyuic4. 我使用pyuic4为主窗口和对话框生成了代码。 What I think should be the relevant code is below. 我认为应该是相关的代码如下。 What am I missing here? 我在这里错过了什么?

class Ui_Dialog(object):
    def __init__(self, dbConnection):
        QtGui.QDialog.__init__(self)
        global c
        c = dbConnection

class Ui_MainWindow(object):
    def __init__(self, dbConnection):
        global c
        c = dbConnection

    def launchEditWindow(self):
        print "DEBUG: Launch edit window"
        dialog = QtGui.QDialog()
        dialogui = Ui_Dialog(c)
        dialogui = setupUi(dialog)
        dialogui.show()

class StartQT4(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        conn = sqlite3.connect('meds.sqlite')
        c = conn.cursor()
        self.ui = Ui_MainWindow(c)
        self.ui.setupUi(self)

def main():
    app = QtGui.QApplication(sys.argv)
    program = StartQT4()
    program.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

Bonus question: since it looks like you can't pass arguments in pyqt function callbacks, is setting something which would otherwise be passed as an argument (the poorly named "c") to be global the best way to get information into those functions? 额外的问题:因为看起来你不能在pyqt函数回调中传递参数,所以设置一些否则将作为参数(名称很简单的“c”)传递给全局的最佳方法来获取这些函数的信息?

I've done like this in the past, and i can tell it works. 我过去做过这样的事情,我可以说它有效。 assuming your button is called "Button" 假设您的按钮被称为“按钮”

class Main(QtGui.QMainWindow):
    ''' some stuff '''
    def on_Button_clicked(self, checked=None):
        if checked==None: return
        dialog = QDialog()
        dialog.ui = Ui_MyDialog()
        dialog.ui.setupUi(dialog)
        dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        dialog.exec_()

This works for my application, and I believe it should work with yours as well. 这适用于我的应用程序,我相信它也应该与您的应用程序一起使用。 hope it'll help, it should be pretty straight forward to do the few changes needed to apply it to your case. 希望它会有所帮助,应该做一些必要的修改才能将它应用到你的案例中。 have a good day everybody. 每个人都过得愉快。

Ui_Dialog should inherent from QtGui.QDialog, not object. Ui_Dialog应该是QtGui.QDialog固有的,而不是对象。

class Ui_Dialog(QtGui.QDialog):
    def __init__(self, dbConnection):
        QtGui.QDialog.__init__(self)
        global c
        c = dbConnection
class StartQT4(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

Why QtGui.QWidget.__init___ ??? 为什么QtGui.QWidget.__init___ ??? Use insted: 使用insted:

class StartQT4(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)

You must call __init__ methon from base class (name in parenthesis '()') 你必须从基类调用__init__ methon(括号'()'中的名字)

QDialog have two useful routins: QDialog有两个有用的例程:

exec_()
show()

First wait for closing dialog and then you can access any field form dialog. 首先等待关闭对话框,然后您可以访问任何字段表单对话框。 Second show dialog but don't wait, so to work properly you must set some slot/signals connections to respond for dialog actions. 第二个显示对话框但不要等待,因此要正常工作,必须设置一些插槽/信号连接以响应对话框操作。

eg. 例如。 for exec_(): 对于exec_():

class Dialog(QDialog):
    def __init__(self, parent):
        QDialog.__init__(parent)
        line_edit = QLineEdit()
    ...

dialog = Dialog()
if dialog.exec_():   # here dialog will be shown and main script will wait for its closing (with no errors)
    data = dialog.line_edit.text()

Small tip: can you change your ui classes into widgets (with layouts). 小提示:您可以将您的ui类更改为小部件(使用布局)。 And perhaps problem is that your __init__ should be __init__(self, parent=None, dbConnection) 也许问题是你的__init__应该是__init__(self, parent=None, dbConnection)

Because when you create new widget in existing one PyQt may try to set it as children of existing one. 因为当您在现有PyTt中创建新窗口小部件时,可能会尝试将其设置为现有窗口小部件。 (So change all init to have additional parent param (must be on second position)). (因此更改所有init以获得额外的父参数(必须在第二个位置))。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM