2

I am trying to build a GUI around some code that I already have. I understand how to do this when building the GUI manually, but am stuck when adding this to the python code generated by Qt Designer and pyuic. As an example, I might need a button which will allow the user to point to a file, which manually I do as such, and this works:

import sys
from PyQt4 import QtGui


class Example(QtGui.QWidget):    
    def __init__(self):
        super(Example, self).__init__()

        self.initUI()

    def initUI(self):        

        btn = QtGui.QPushButton('Open File', self)
        btn.setToolTip('This is a <b>QPushButton</b> widget')
        btn.resize(btn.sizeHint())
        btn.move(50, 50)     
        btn.clicked.connect(self.loadFile)

        self.setGeometry(300, 300, 250, 150)
        self.show()

    def loadFile(self):
        fname = QtGui.QFileDialog.getOpenFileName(self, 'Open file', '/home')
        # some custom code for reading file and storing it

def main():
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

However, when I try to do the same in Qt Designer code the program stops before reaching the file dialog.

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.resize(400, 300)
        self.pushButton = QtGui.QPushButton(Form)
        self.pushButton.setGeometry(QtCore.QRect(130, 100, 75, 23))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))

        self.retranslateUi(Form)
        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL(_fromUtf8("clicked()")), self.loadFile)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        Form.setWindowTitle(_translate("Form", "Form", None))
        self.pushButton.setText(_translate("Form", "Open File", None))

    def loadFile(self):
        print('loadFile1')
        fname = QtGui.QFileDialog.getOpenFileName(self, 'Open file', '/home')
        print('loadFile2')


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

This only prints the first statement in loadFile(), but does not open up the file dialog window. What am I doing wrong?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • (1) Read the comment at the top of the generated file: `# WARNING! All changes made in this file will be lost!`. (2) Read the PyQt docs: [Using Qt Designer](http://pyqt.sourceforge.net/Docs/PyQt4/designer.html). (3) Run the code in an environment that can show Python tracebacks. – ekhumoro Jan 11 '17 at 20:31

2 Answers2

1

According to the documentation:

QString getOpenFileName (QWidget parent = None, QString caption = '', QString directory = '', QString filter = '', Options options = 0)

QString getOpenFileName (QWidget parent = None, QString caption = '', QString directory = '', QString filter = '', QString selectedFilter = '', Options options = 0)

You need to pass as a parent a widget or None, in your case self is not of type object.

You must change

 QtGui.QFileDialog.getOpenFileName(self, 'Open file', '/home')

to

QtGui.QFileDialog.getOpenFileName(None, 'Open file', '/home')
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
1

I really don't like using pyuic as long as I can avoid. There's an easier way you may try, it reduces your code. Say your UI file is called something.ui, and you have named your button in QT Designer somebutton, then the code will be:

from PyQt4 import QtCore, QtGui, uic
Ui_somewindow, _ = uic.loadUiType("something.ui") #the path to your UI

class SomeWindow(QtGui.QMainWindow, Ui_somewindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        Ui_somewindow.__init__(self)
        self.setupUi(self)
        self.somebutton.clicked.connect(self.loadFile)

   def loadFile(self):
        print('loadFile1')
        fname = QtGui.QFileDialog.getOpenFileName(self, 'Open file', '/home')
        print('loadFile2')

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = SomeWindow()
    window.show()
    sys.exit(app.exec_())

Note that if you have QDialog replace QMainWindow with QDialog. Hope this helps.

Kit A.
  • 80
  • 7