简体   繁体   中英

PyQt4 enable button on text entry, connect windows

I am attempting to write a gui program in python but have virtually no experience in gui programming. I starting learning tkinter and picked up most of what I need to know for the purposes of my program, but I recently discovered PyQt and Qt designer, and the output looks a lot nicer.

In my program, I want to first open a small window that prompts the user for some information (that it will use to load a file or create a new file). Because this information is crucial, I don't want the user to be able to progress from the first small window without entering it so I want the 'OK' button to be disabled initially and enabled when the user enters information into the field. I have made an attempt at this (mostly created in Qt Designer and then edited) which is shown below.

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'open.ui'
#
# Created: Wed Jun 25 17:51:25 2014
#      by: PyQt4 UI code generator 4.10.3
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName(_fromUtf8("Form"))
        Form.setEnabled(True)
        Form.resize(308, 143)
        self.horizontalLayout = QtGui.QHBoxLayout(Form)
        self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
        self.verticalLayout = QtGui.QVBoxLayout()
        self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
        self.horizontalLayout_3 = QtGui.QHBoxLayout()
        self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3"))
        spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
        self.horizontalLayout_3.addItem(spacerItem)
        self.label = QtGui.QLabel(Form)
        self.label.setObjectName(_fromUtf8("label"))
        self.horizontalLayout_3.addWidget(self.label)
        spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
        self.horizontalLayout_3.addItem(spacerItem1)
        self.verticalLayout.addLayout(self.horizontalLayout_3)
        self.horizontalLayout_7 = QtGui.QHBoxLayout()
        self.horizontalLayout_7.setObjectName(_fromUtf8("horizontalLayout_7"))
        self.label_2 = QtGui.QLabel(Form)
        self.label_2.setObjectName(_fromUtf8("label_2"))
        self.horizontalLayout_7.addWidget(self.label_2)
        self.lineEdit = QtGui.QLineEdit(Form)
        self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
        self.horizontalLayout_7.addWidget(self.lineEdit)
        self.verticalLayout.addLayout(self.horizontalLayout_7)
        self.horizontalLayout_8 = QtGui.QHBoxLayout()
        self.horizontalLayout_8.setObjectName(_fromUtf8("horizontalLayout_8"))
        self.label_3 = QtGui.QLabel(Form)
        self.label_3.setObjectName(_fromUtf8("label_3"))
        self.horizontalLayout_8.addWidget(self.label_3)
        self.lineEdit_2 = QtGui.QLineEdit(Form)
        self.lineEdit_2.setObjectName(_fromUtf8("lineEdit_2"))
        self.horizontalLayout_8.addWidget(self.lineEdit_2)
        self.verticalLayout.addLayout(self.horizontalLayout_8)
        self.horizontalLayout_9 = QtGui.QHBoxLayout()
        self.horizontalLayout_9.setObjectName(_fromUtf8("horizontalLayout_9"))
        self.pushButton_2 = QtGui.QPushButton(Form)
        self.pushButton_2.setEnabled(False)
        self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
        self.horizontalLayout_9.addWidget(self.pushButton_2)
        self.pushButton = QtGui.QPushButton(Form)
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.horizontalLayout_9.addWidget(self.pushButton)
        self.verticalLayout.addLayout(self.horizontalLayout_9)
        self.horizontalLayout.addLayout(self.verticalLayout)

        self.retranslateUi(Form)
        QtCore.QObject.connect(self.lineEdit_2, QtCore.SIGNAL(_fromUtf8("textEdited(QString)")), self.pushButton_2.setEnabled)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        Form.setWindowTitle(_translate("Form", "Form", None))
        self.label.setText(_translate("Form", "Please enter your name and student number:", None))
        self.label_2.setText(_translate("Form", "Name: ", None))
        self.label_3.setText(_translate("Form", "Student number: ", None))
        self.pushButton_2.setText(_translate("Form", "OK", None))
        self.pushButton.setText(_translate("Form", "Cancel", None))


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    Form = QtGui.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

When I run the program and type something into the student number field it gives the following error: TypeError: QWidget.setEnabled(bool): argument 1 has unexpected type 'str' . I realise that the problem is that the it is taking a string as an input rather than a boolean but I don't know how to fix it.

The second part of my problem is that I want a new bigger window to open when the user clicks 'OK' on the small window, this window will have a next option at the bottom where it progresses to another similar window but I have no idea how to do this (link windows that is).

How do I do the things mentioned above? Or should I just stick to tkinter even though it seems to me to be aesthetically inferior. Thanks.

Firstly you should never write code into the generated UI file from Qt Designer as this gets overwritten by the pyuic tool the next time you write to it. Instead import it into a seperate file.

This line needs to be removed from your Ui_File:

QtCore.QObject.connect(self.lineEdit_2, QtCore.SIGNAL(_fromUtf8("textEdited(QString)")), self.pushButton_2.setEnabled)

Example:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from PyQt4.QtCore import pyqtSlot
from PyQt4.QtGui import QWidget, QApplication
#assumes your file is called Ui_Main_Form.py from the pyuic tool
from Ui_Main_Form import Ui_Form


class MainForm(QWidget):
    def __init__(self, parent=None):
        #Initialise
        super(MainForm, self).__init__(parent)

        #Setup the UI
        self.ui = Ui_Form()
        self.ui.setupUi(self)

        #Now can do any modifications that cant be done in Qt Designer
        #Handle the textChanged signal for QLineEdit
        self.ui.lineEdit_2.textChanged.connect(self.line_edit_text_changed)


    @pyqtSlot(str)
    def line_edit_text_changed(self, text):
        if text:  # Check to see if text is filled in
            self.ui.pushButton_2.setEnabled(True)
        else:
            self.ui.pushButton_2.setEnabled(False)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    my_form = MainForm()
    my_form.show()
    sys.exit(app.exec_())

There is some useful information on the signal and slots mechanism for PyQt here

For how to launch windows from this one see this: How to create new PyQt4 windows from an existing window? accepted answer.

Hope this gets you started.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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