Pergunta

Eu estou tentando usar PyQt para mostrar uma janela QDialog personalizada quando um botão em um QMainWindow é clicado. Recebo o seguinte erro:

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

Eu tenho ido ao longo de vários tutoriais on-line, mas a maioria deles parar um pouco de mostrar como usar um não built-in janela de diálogo. I gerado o código para a janela principal e a caixa de diálogo usando pyuic4. O que eu acho que deve ser o código relevante é inferior. O que estou ausente aqui?

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

Bônus pergunta: uma vez que parece que você não pode passar argumentos em chamadas de retorno de função PyQt, está definindo algo que de outra forma seria passado como um argumento (o mal chamado "c") para ser global a melhor maneira de obter informações em essas funções?

Foi útil?

Solução

Eu tenho feito assim no passado, e eu posso dizer que funciona. Assumindo que o seu botão é chamado de "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_()

Isso funciona para a minha candidatura, e eu acredito que deve funcionar com o seu bem. Esperamos que ele vai ajudar, deve ser bastante simples de fazer poucas mudanças necessárias para aplicá-lo ao seu caso. tenha um bom dia a todos.

Outras dicas

Ui_Dialog deve inerente de QtGui.QDialog, não objeto.

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)

Por QtGui.QWidget.__init___ ??? Use insted:

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

Você deve chamar methon __init__ de classe base (nome entre parênteses '()')

QDialog tem duas routins úteis:

exec_()
show()

Primeiro espera para diálogo fechar e, em seguida, você pode acessar qualquer diálogo forma campo. diálogo segundo show, mas não espere, então ao trabalho corretamente, você deve definir alguns fenda / sinais conexões para responder a acções de diálogo.

por exemplo. para 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()

Uma pequena dica: você pode mudar suas aulas ui em widgets (com layouts). E talvez problema é que seu __init__ deve ser __init__(self, parent=None, dbConnection)

Porque quando você criar um novo widget no já existente PyQt pode tentar defini-lo como filhos de um já existente. (Então, mudar tudo init para ter param pai adicional (deve estar na segunda posição)).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top