views:

256

answers:

1

I am working on an application using PyQt4 and the designer it provides. I have a main window application that works fine, but I wanted to create custom message dialogs. I designed a dialog and set up some custom signal/slot connections in the __init__ method and wrote an if __name__=='__main__': and had a test. The custom slots work fine. However, when I create an instance of my dialog from my main window application, none of the buttons work. Here is my dialog:

from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys
import encode_dialog_ui

# Ui_EncodeDialog is the python class generated by pyuic4 from the Designer
class EncodeDialog(encode_dialog_ui.Ui_EncodeDialog):

    def __init__(self, parent, in_org_im, txt_file, in_enc_im):
        self.qd = QDialog(parent)
        self.setupUi(self.qd)
        self.qd.show()
        self.message = (txt_file.split("/")[-1] + " encoded into " + 
            in_org_im.split("/")[-1] + " and written to " + 
            in_enc_im.split("/")[-1] + ".")

        QObject.connect(self.view_image_button, SIGNAL("clicked()"),
                        self.on_view_image_button_press)

        self.org_im = in_org_im
        self.enc_im = in_enc_im

        self.encoded_label.setText(self.message)       

    def on_view_image_button_press(self):
        print "hello world"

if __name__ == '__main__':
    app = QApplication(sys.argv)
    tmp = QMainWindow()
    myg = EncodeDialog(tmp,'flower2.png','b','flower.png')
    app.exec_()

If I run this class it works fine, and pressing the view_image_button prints hello world to the console. However when I use the call

#self.mw is a QMainWindow, the rest are strings
EncodeDialog(self.mw, self.encode_image_filename, 
             self.encode_txt_filename, 
             self.encode_new_image_filename)

in my main window class, the dialog displays correctly but the view_image_button does nothing when clicked. I have googled for a solution, but couldn't find anything useful. Let me know if you need any more information. Any help on this would be appreciated!

As requested below is some more code from my main window class for brevity's sake I have added ellipses to remove code that seemed irrelevant. If no one can think of anything still, I will add more. (If indenting is a little off, it happened in copy-pasting. The orignal code is correct)

class MyGUI(MainWindow.Ui_MainWindow):

    def __init__(self):
        self.mw = QMainWindow()
        self.setupUi(self.mw)
        self.mw.show()

        self.encode_red_bits = 1
        self.encode_blue_bits = 1
        self.encode_green_bits = 1

        self.decode_red_bits = 1
        self.decode_blue_bits = 1
        self.decode_green_bits = 1

        self.encode_image_filename = ""
        self.encode_new_image_filename = ""
        self.encode_txt_filename = ""

        self.decode_image_filename = ""
        self.decode_txt_filename = ""

        # Encode events 
        ...
        QObject.connect(self.encode_button, SIGNAL("clicked()"),
                        self.on_encode_button_press)

        # Decode events
        ...


    # Encode event handlers
    ...

    def on_encode_button_press(self):
        tmp = QErrorMessage(self.mw)
        if (self.encode_image_filename != "" and 
            self.encode_new_image_filename != "" and
            self.encode_txt_filename != ""):


            try:
                im = Steganography.encode(self.encode_image_filename, self.encode_txt_filename, 
                                          self.encode_red_bits, self.encode_green_bits,
                                          self.encode_blue_bits)
                im.save(self.encode_new_image_filename)
                encode_dialog.EncodeDialog(self.mw, self.encode_image_filename,
                                           self.encode_txt_filename, 
                                           self.encode_new_image_filename)
            except Steganography.FileTooLargeException:
                tmp.showMessage(self.encode_txt_filename.split("/")[-1] + 
                                " is to large to be encoded into " +
                                self.encode_image_filename.split("/")[-1])

        else:
            tmp.showMessage("Please specify all filenames.")


    # Decode event handlers
    ...


if __name__ == '__main__':
    app = QApplication(sys.argv)
    myg = MyGUI()
    app.exec_()
A: 

It feels like the signal is just not getting passed from the parent down to your child QDIalog.

Try these suggestions:

  1. Use the new method for connecting signals
  2. Instead of extending the classes pyuic created, extend the actual QT classes and call the ones generated by pyuic

Your new code will look something like this:

    class MyGUI(QMainWindow):
        def __init__(self, parent=None):
            QMainWindow.__init__(self, parent)
            self.mw = MainWindow.Ui_MainWindow()
            self.mw.setupUi(self)
            self.mw.show()
            ...
            self.encode_button.clicked.connect(self.on_encode_button_press)
            ...

    class EncodeDialog(QDialog):
        def __init__(self, parent, in_org_im, txt_file, in_enc_im):
            QDialog.__init__(self, parent)
            self.qd = encode_dialog_ui.Ui_EncodeDialog()
            self.qd.setupUi(self)
            self.qd.show()
            ...
            self.view_image_button.clicked.connect(self.on_view_image_button_press)
            ...
jcoon
Thanks for the ideas, but I'm not getting anywhere with this. The problem is that Ui_EncodeDialog doesn't have methods like show() and QDialog doesn't have the buttons or labels necessary. I tried fiddling around with it, and I did get it to display the dialog, however the buttons didn't even work using the `__name__="__main__"` method. I'll keep playing with it, but as yet I still don't have a solution. Thanks for all the help though!
ZVarberg