【问题标题】:Open a second window in PyQt在 PyQt 中打开第二个窗口
【发布时间】:2025-12-22 11:25:13
【问题描述】:

我正在尝试使用 pyqt 在单击 QMainWindow 上的按钮时显示自定义 QDialog 窗口。我不断收到以下错误:

$ 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'

我浏览了几个在线教程,但其中大多数都没有展示如何使用非内置对话窗口。我使用 pyuic4 为主窗口和对话框生成了代码。我认为应该是相关代码如下。我在这里错过了什么?

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()

额外的问题:因为看起来你不能在 pyqt 函数回调中传递参数,所以将一些本来可以作为参数传递的东西(名称不佳的“c”)设置为全局,这是获取信息的最佳方式那些功能?

【问题讨论】:

  • Ui_MainWindow.__init__ 有一个参数:dbConnection 你似乎没有通过:self.ui = Ui_MainWindow() - 你的代码怎么能工作?
  • 哎呀。我暂时删除了中间问题中的数据库内容,以查看它是否是问题的一部分。然后我忘记重新复制并重新粘贴代码后重新粘贴。

标签: python dialog pyqt


【解决方案1】:

我过去做过这样的事情,我可以说它有效。 假设您的按钮被称为“按钮”

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_()

这适用于我的应用程序,我相信它也适用于您的应用程序。希望它会有所帮助,应该非常直接地进行一些更改以将其应用于您的案例。 祝大家有个美好的一天。

【讨论】:

    【解决方案2】:

    Ui_Dialog 应该来自 QtGui.QDialog,而不是对象。

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

    【讨论】:

      【解决方案3】:
      class StartQT4(QtGui.QMainWindow):
          def __init__(self, parent=None):
              QtGui.QWidget.__init__(self, parent)
      

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

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

      您必须从基类调用__init__methon(括号'()'中的名称)

      QDialog 有两个有用的例程:

      exec_()
      show()
      

      首先等待关闭对话框,然后您可以访问任何字段表单对话框。第二次显示对话框,但不要等待,因此要正常工作,您必须设置一些插槽/信号连接以响应对话框操作。

      例如。对于 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()
      

      小提示:您能否将您的 ui 类更改为小部件(带有布局)。也许问题是你的__init__ 应该是__init__(self, parent=None, dbConnection)

      因为当您在现有的小部件中创建新小部件时,PyQt 可能会尝试将其设置为现有小部件的子级。 (因此将所有初始化更改为具有额外的父参数(必须在第二个位置)。

      【讨论】:

      • 好的。但是我的程序仍然和以前一样。知道为什么我在尝试打开第二个窗口时收到错误“descriptor 'init' requires a 'sip.simplewrapper' object but received a 'Ui_Dialog'”?
      最近更新 更多