我试图将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_())
我希望你能帮助我,我会感激任何提示。谢谢!
答案 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)
您发布的示例代码至少有三个问题:
您正在尝试传递可调用对象的返回值,而不是可调用对象本身。因此,从最后一个参数中删除括号:
QtCore.QObject.connect(self.ui.comboBox,
QtCore.SIGNAL("currentIndexChanged()"),
self.comboBoxIndexChanged)
您正在尝试在定义之前引用可调用对象。这是由于可能是缩进错误 - 所以受影响的部分应该是这样的,而不是:
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
当您使用优雅和pythonic old-style signal and slot syntax时,您正在使用丑陋且容易出错的new-style syntax。请帮个忙,写下你所有的信号连接:
self.ui.comboBox.currentIndexChanged.connect(self.comboBoxIndexChanged)