PyQt: 'ConverterDialog' 对象没有属性 'comboBoxIndexChanged'
PyQt: 'ConverterDialog' object has no attribute 'comboBoxIndexChanged'
我正在尝试将组合框连接到 class ConverterDialog 中的插槽。我不知道为什么(插槽连接在 classes 中非常相似),但它不起作用。我认为这是一个简单的问题,但我是 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_())
我希望你能帮助我,我会很感激任何提示。谢谢!
你的连接语句应该是这样的:
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)
您发布的示例代码至少存在三处错误:
您正试图传递可调用对象的 return 值,而不是可调用对象本身。所以从最后一个参数中删除括号:
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
您正在使用丑陋且容易出错的 old-style signal and slot syntax, when you could be using the elegant and pythonic new-style syntax。请帮自己一个忙,像这样写下你所有的信号连接:
self.ui.comboBox.currentIndexChanged.connect(self.comboBoxIndexChanged)
我正在尝试将组合框连接到 class ConverterDialog 中的插槽。我不知道为什么(插槽连接在 classes 中非常相似),但它不起作用。我认为这是一个简单的问题,但我是 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_())
我希望你能帮助我,我会很感激任何提示。谢谢!
你的连接语句应该是这样的:
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)
您发布的示例代码至少存在三处错误:
您正试图传递可调用对象的 return 值,而不是可调用对象本身。所以从最后一个参数中删除括号:
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
您正在使用丑陋且容易出错的 old-style signal and slot syntax, when you could be using the elegant and pythonic new-style syntax。请帮自己一个忙,像这样写下你所有的信号连接:
self.ui.comboBox.currentIndexChanged.connect(self.comboBoxIndexChanged)