PyQt:'ConverterDialog'对象没有属性'comboBoxIndexChanged'

时间:2015-02-23 02:02:21

标签: python qt pyqt

我试图将comboBox连接到ConverterDialog类中的插槽。我不知道为什么(两个类中的插槽连接非常相似),但它不起作用。我认为这是一个简单的问题,但我是python的新手,我无法看到它。以下是错误消息:

Traceback (most recent call last):
  File "test.py", line 130, in genImp
    self.converterDialog = ConverterDialog(self)
  File "test.py", line 182, in __init__
    QtCore.QObject.connect(self.ui.comboBox, QtCore.SIGNAL("currentIndexChanged()"), self.comboBoxIndexChanged())
AttributeError: 'ConverterDialog' object has no attribute 'comboBoxIndexChanged'      

代码:

   import sys
    from PyQt4 import QtCore, QtGui
    from mainwindow import Ui_Converter, Ui_ConverterDialog
    class MainWindow(QtGui.QMainWindow):




        def __init__(self, parent=None):
            QtGui.QWidget.__init__(self, parent)
            self.ui = Ui_Converter()
            self.ui.setupUi(self)
            self.ui.textEditSrcPath.setReadOnly(True)
            self.ui.textEditDstPath.setReadOnly(True)
            self.ui.pushButtonGenImp.setEnabled(True)
        #slots
            QtCore.QObject.connect(self.ui.toolButtonDstPath, QtCore.SIGNAL("clicked()"), self.openDirFileDialog)
            QtCore.QObject.connect(self.ui.toolButtonSrcPath, QtCore.SIGNAL("clicked()"), self.openFileDialog)
            QtCore.QObject.connect(self.ui.pushButtonGenSlides, QtCore.SIGNAL("clicked()"), self.genSlides)
            QtCore.QObject.connect(self.ui.pushButtonGenImp, QtCore.SIGNAL("clicked()"), self.genImp)




        def openDirFileDialog(self):
            if self.ui.pushButtonGenImp.isEnabled():
                response = False
                cancel = 'Cancel'
                discard = 'Discard'

                message = QtGui.QMessageBox(self)
                message.setText('Changing a path will discard previously generated (as images) slides.')
                message.setWindowTitle('Warning!')
                message.setIcon(QtGui.QMessageBox.Warning)
                message.addButton(cancel, QtGui.QMessageBox.RejectRole)
                message.addButton(discard, QtGui.QMessageBox.DestructiveRole)
                message.exec_()

                response = message.clickedButton().text()

                if response == discard:
                    self.ui.pushButtonGenImp.setEnabled(False)
                    fd = QtGui.QFileDialog(self)
                    fd.ShowDirsOnly
                    self.filename = fd.getExistingDirectory()
                    self.ui.textEditDstPath.setText(self.filename)
                elif response != discard:
                    self.ui.pushButtonGenImp.setEnabled(True)
            else:
                fd = QtGui.QFileDialog(self)
                fd.ShowDirsOnly
                self.filename = fd.getExistingDirectory()
                self.ui.textEditDstPath.setText(self.filename)


        def openFileDialog(self):
            if self.ui.pushButtonGenImp.isEnabled():
                response = False
                cancel = 'Cancel'
                discard = 'Discard'

                message = QtGui.QMessageBox(self)
                message.setText('Changing a path will discard previously generated (as images) slides.')
                message.setWindowTitle('Warning!')
                message.setIcon(QtGui.QMessageBox.Warning)
                message.addButton(cancel, QtGui.QMessageBox.RejectRole)
                message.addButton(discard, QtGui.QMessageBox.DestructiveRole)
                message.exec_()

                response = message.clickedButton().text()

                if response == discard:
                    self.ui.pushButtonGenImp.setEnabled(False)
                elif response != discard:
                    self.ui.pushButtonGenImp.setEnabled(True)
            else:
                fd = QtGui.QFileDialog(self)
                self.filename = fd.getOpenFileName(self, "Select File", "/home", "Presentations | *.odp *.ppt *.pptx (*.odp *.ppt *.pptx)")
                self.ui.textEditSrcPath.setText(self.filename)


        def genSlides(self):
            self.filename = self.ui.textEditSrcPath.toPlainText()
            self.dirname = self.ui.textEditDstPath.toPlainText()
            from os.path import isfile, isdir
            if isfile(self.filename) and isdir(self.dirname):  # check validity of paths
                import subprocess
                ### call 'whereis soffice' to find the path of soffice ###
                soffice = subprocess.Popen(["whereis","soffice"], stdout=subprocess.PIPE)
                sofficeOutput, sofficeErr = soffice.communicate() # getting output of called command

                ### formatting string containing path of soffice package ###
                sofficeOutput = sofficeOutput[9:len(sofficeOutput)]
                pos = sofficeOutput.find('soffice', 0, len(sofficeOutput))
                #if pos == -1:
                # TODO: exception handler
                sofficePath = sofficeOutput[0:(pos + 7)]

                ### having soffice path known, converting to pdf can be done ###
                subprocess.call([sofficePath,"--headless","--convert-to", "pdf","--outdir",self.dirname, self.filename])
                #import time
                #time.sleep(5)
                ### having pdf, generating thumbnails (.jpeg/.png) can be done ###

                #getting extension from combobox
                if self.ui.comboBoxExt.currentText() == "*.jpeg":
                    extension = ".jpeg"
                else:
                    extension = ".png"
                #getting width and height from properties
                width = self.ui.spinBoxWidth.value()
                height = self.ui.spinBoxHeight.value()

                #getting path of pdf
                posPdf = str(self.filename).rfind('/',0,len(self.filename)) #position of last slash in filename to get name
                posExt = str(self.filename).rfind('.',0,len(self.filename)) #position of presentation extension
                cutExt = len(self.filename) - (posExt+1)
                pdfPath = self.dirname + '/' + self.filename[(posPdf+1):(len(self.filename)-cutExt)] + 'pdf'

                #converting using Imagemagick package
                subprocess.call(["convert","-thumbnail",str(width)+"x"+str(height),pdfPath, self.dirname+"/slide"+extension])

                #pdf is not needed anymore
                subprocess.call(["rm",pdfPath])

                #enabling buttonGenImp
                self.ui.pushButtonGenImp.setEnabled(True)

        def genImp(self):
            self.converterDialog = ConverterDialog(self)
            self.converterDialog.setWindowFlags(QtCore.Qt.Window)
            self.converterDialog.show()





    class ConverterDialog(QtGui.QDialog):
        def __init__(self, parent = None):
            QtGui.QDialog.__init__(self, parent)
            self.ui = Ui_ConverterDialog()
            self.ui.setupUi(self)

            slidesPath = str(myapp.ui.textEditDstPath.toPlainText())
            extension = ".jpeg"

            #getting number of slides in the presentation
            import subprocess, shlex
            find = "find "+slidesPath+" -type f -name slide-\\*"+extension+" | wc -l" # get number of files in directory named "slide-*.jpg"
            slidesNumber = int(subprocess.check_output(find, shell=True))

            #filling combobox
            slides = []
            for i in range(slidesNumber):
                slides.append("slide-"+str(i)+extension)
            self.ui.comboBox.addItems(slides)

            #getting resolution of image and filling labelResolution
            slide = QtGui.QPixmap(slidesPath+"/slide-0"+extension)
            slideHeight = slide.height()
            slideWidth = slide.width()
            self.ui.labelResolution.setText("The resolution of slides is: "+str(slideWidth)+"x"+str(slideHeight))       
            #slots
            QtCore.QObject.connect(self.ui.comboBox, QtCore.SIGNAL("currentIndexChanged()"), self.comboBoxIndexChanged())
            def comboBoxIndexChanged(self):
                return 1




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

我希望你能帮助我,我会感激任何提示。谢谢!

2 个答案:

答案 0 :(得分:1)

你的连接声明应该是:

QtCore.QObject.connect(self.ui.comboBox, QtCore.SIGNAL("currentIndexChanged()"), self, QtCore.SLOT("comboBoxIndexChanged()))

QtCore.QObject.connect(self.ui.comboBox, QtCore.SIGNAL("currentIndexChanged()"), QtCore.SLOT("comboBoxIndexChanged()))

更简单的形式是:

self.ui.currentIndexChanged.connect(comboBoxIndexChanged)

答案 1 :(得分:0)

您发布的示例代码至少有三个问题:

  1. 您正在尝试传递可调用对象的返回值,而不是可调用对象本身。因此,从最后一个参数中删除括号:

    QtCore.QObject.connect(self.ui.comboBox,
                           QtCore.SIGNAL("currentIndexChanged()"),
                           self.comboBoxIndexChanged)
    
  2. 您正在尝试在定义之前引用可调用对象。这是由于可能是缩进错误 - 所以受影响的部分应该是这样的,而不是:

    class ConverterDialog(QtGui.QDialog):
        def __init__(self, parent = None):
            ...
            QtCore.QObject.connect(self.ui.comboBox,
                                   QtCore.SIGNAL("currentIndexChanged()"),
                                   self.comboBoxIndexChanged)
    
        def comboBoxIndexChanged(self):
            return 1
    
  3. 当您使用优雅和pythonic old-style signal and slot syntax时,您正在使用丑陋且容易出错的new-style syntax。请帮个忙,写下你所有的信号连接:

    self.ui.comboBox.currentIndexChanged.connect(self.comboBoxIndexChanged)