Issue
In PyQt, I have a basic program. It consists of 2 combo boxes, 1 line edit and 3 checkboxes. What I want to do is, depending on the item of the first combo box, hide / show specific widgets. However, I keep getting an error: 'ExportDialog' object has no attribute 'exportSetDelimiter_lbl'. I have defined this widget above in
initUI, and I run
initUIin
init`, so I'm not sure why I am getting this error. Here is my code:
from PyQt5 import QtGui, QtCore, QtWidgets
import sys
class ExportDialog(QtWidgets.QMainWindow):
def __init__(self,imagePath):
super(ExportDialog, self).__init__()
self.initUI(imagePath)
#Set The GUI Position And Size
self.setGeometry(500, 500, 600, 450)
#Set The GUI Title
self.setWindowTitle("Export Deck")
#Set The GUI Icon
self.setWindowIcon(QtGui.QIcon('MainFlashcardAppIcon.png'))
def initUI(self, PATH):
#Create The New Deck Label
self.exportFormat_lbl = QtWidgets.QLabel(self)
self.exportFormat_lbl.setText("Export Format: ")
exportFormat_font = QtGui.QFont()
exportFormat_font.setPointSize(8)
self.exportFormat_lbl.setFont(exportFormat_font)
self.exportFormat_lbl.adjustSize()
self.exportFormat_combo = QtWidgets.QComboBox()
self.exportFormat_combo.setMinimumHeight(35)
self.exportFormat_combo.setFixedWidth(380)
self.exportFormat_combo.currentTextChanged.connect(self.on_combobox_changed)
self.exportDeckName_lbl = QtWidgets.QLabel(self)
self.exportDeckName_lbl.setText("Include: ")
self.exportDeckName_lbl.setFont(exportFormat_font)
self.exportDeckName_lbl.adjustSize()
self.exportDeckName_combo = QtWidgets.QComboBox()
self.exportDeckName_combo.setMinimumHeight(35)
self.exportDeckName_combo.setFixedWidth(380)
self.exportFormat_combo.addItem(".TXT")
self.exportFormat_combo.addItem(".CSV")
self.exportFormat_combo.addItem(".DB")
self.exportSetDelimiter_lbl = QtWidgets.QLabel()
self.exportSetDelimiter_lbl.setText("Set Delimiter (Leave blank for standard delimited):")
self.exportSetDelimiter_txt = QtWidgets.QLineEdit()
self.exportSetDelimiter_txt.setMaxLength(1)
self.exportSetDelimiter = QtWidgets.QLineEdit()
vboxExport_setDelimiter = QtWidgets.QVBoxLayout()
vboxExport_setDelimiter.addWidget(self.exportSetDelimiter_lbl)
vboxExport_setDelimiter.addWidget(self.exportSetDelimiter_txt)
self.includeMedia_check = QtWidgets.QCheckBox("Include HTML and Media References")
self.includeTags_check = QtWidgets.QCheckBox("Include Tags")
self.includeAllSQL_check = QtWidgets.QCheckBox("Include All SQL Tables")
self.exportFormat_combo.addItem("B3 Biology")
self.exportFormat_combo.addItem("B2 Biology")
self.exportFormat_combo.addItem("B1 Biology")
self.allComboList = ["B3 Biology", "B2 Biology", "B1 Biology"]
self.exportDeckName_combo.setCurrentIndex(self.allComboList.index(PATH))
#Create Confirm Button
self.confirmButton = QtWidgets.QPushButton(self)
self.confirmButton.setText("OK")
self.confirmButton.clicked.connect(self.createDeck)
#Create Cancel Button
self.cancelButton = QtWidgets.QPushButton(self)
self.cancelButton.setText("Cancel")
self.cancelButton.clicked.connect(self.close)
hboxExportFormat = QtWidgets.QHBoxLayout()
hboxExportFormat.addWidget(self.exportFormat_lbl)
hboxExportFormat.addStretch()
hboxExportFormat.addWidget(self.exportFormat_combo)
hboxExportName = QtWidgets.QHBoxLayout()
hboxExportName.addWidget(self.exportDeckName_lbl)
hboxExportName.addStretch()
hboxExportName.addWidget(self.exportDeckName_combo)
hboxButtonsBottom = QtWidgets.QHBoxLayout()
hboxButtonsBottom.addStretch()
hboxButtonsBottom.addWidget(self.confirmButton)
hboxButtonsBottom.addWidget(self.cancelButton)
#Create The VBoxLayout
mainLayout = QtWidgets.QVBoxLayout(self)
mainLayout.addLayout(hboxExportFormat)
mainLayout.addLayout(hboxExportName)
mainLayout.addLayout(vboxExport_setDelimiter)
mainLayout.addWidget(self.includeMedia_check)
mainLayout.addWidget(self.includeTags_check)
mainLayout.addWidget(self.includeAllSQL_check)
mainLayout.addStretch()
mainLayout.addLayout(hboxButtonsBottom)
def on_combobox_changed(self, i):
if i == ".TXT":
self.exportSetDelimiter_lbl.show()
self.exportSetDelimiter_txt.show()
self.includeMedia_check.show()
self.includeTags_check.show()
self.includeAllSQL_check.hide()
elif i == ".CSV":
self.exportSetDelimiter_lbl.hide()
self.exportSetDelimiter_txt.hide()
self.includeMedia_check.show()
self.includeTags_check.show()
self.includeAllSQL_check.hide()
elif i == ".DB":
self.exportSetDelimiter_lbl.hide()
self.exportSetDelimiter_txt.hide()
self.includeMedia_check.show()
self.includeTags_check.show()
self.includeAllSQL_check.show()
def createDeck(self):
print("Exported Sucessfully")
self.close()
#Create A Windows
app = QtWidgets.QApplication(sys.argv)
window = ExportDialog("B1 Biology")
window.show()
sys.exit(app.exec_())
This is my first question, so if you need any additional information, I will add it in. Any help would be much appreciated. Thank you!
Solution
When a combobox is newly created, it has an invalid current index (-1
) and no current text set. As soon as the first item is added, the index is automatically updated to 0
and the current text changes to that of the item.
You've connected to the currentTextChanged
signal before adding new items, and since the function currentTextChanged
assumes that the whole ui has been already created (including exportSetDelimiter_lbl
), you get the attribute error.
While there's no rule for the placing of signal connections, it's usually a good habit to group all connections at the end of the function that creates them, or anyway, ensure that everything required by their connection has already been created.
So, just move the signal connection at the end of initUI
and everything will work fine.
Well... No. Because you didn't set a central widget for the main window and tried to set the layout on it (which is not allowed, since a QMainWindow has a private and unaccessible layout).
Add a QWidget, call self.setCentralWidget(someWidget)
and create the layout for that widget.
Answered By - musicamante
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.