The Labels
self.titlelabel = QLabel(self)
self.artistlabel = QLabel(self)
self.albumlabel = QLabel(self)
in the UI do not update, when i run the method.
I mean, they do work on the initial initialization of the initUI(self), but when i change the item in the combobox, the do not update with the new information
I run this command in the initUI(self) which is connected to the dropdown /Qcombobox self.cb.activated.connect(self.updateTrackInfo)
def currentTrackInfo(self):
currentTrackInfoDict = {}
currentZone = str(self.cb.currentText())
deviceDict = self.sonosZonesCoordinatorsIP()
for key, value in deviceDict.items():
if value == currentZone:
device = SoCo(key)
track = device.get_current_track_info()
current_title = track['title']
current_artist = track["artist"]
current_album = track["album"]
currentTrackInfoDict.update({"current_title":current_title})
currentTrackInfoDict.update({"current_artist":current_artist})
currentTrackInfoDict.update({"current_album":current_album})
return currentTrackInfoDict
def updateTrackInfo(self):
self.currentTrackInfoDict = self.currentTrackInfo()
self.titlelabel = QLabel(self)
self.artistlabel = QLabel(self)
self.albumlabel = QLabel(self)
self.titlelabel.move((PLAYICONHEIGHT-100),(WINDOWHEIGHT-230))
self.artistlabel.move((PLAYICONHEIGHT-100),(WINDOWHEIGHT-220))
self.albumlabel.move((PLAYICONHEIGHT-100),(WINDOWHEIGHT-250))
self.titlelabel.setText("Title: {}".format(self.currentTrackInfoDict["current_title"]))
print(self.currentTrackInfoDict["current_title"])
self.artistlabel.setText("Artist: {}".format(self.currentTrackInfoDict["current_artist"]))
self.albumlabel.setText("Album: {}".format(self.currentTrackInfoDict["current_album"]))
The print function : print(self.currentTrackInfoDict["current_title"]) - works, but the labels are not being updated.
thank you in advance.
In your updateTrackInfo method each time you create the new QLabel objects instead of just updating the text on the existing ones. It may cause a problems since the new labels overlap with old (you are not deleting the old labels and they still exist after updateTrackInfo is called). I would suggest to move
self.titlelabel = QLabel(self)
self.artistlabel = QLabel(self)
self.albumlabel = QLabel(self)
self.titlelabel.move((PLAYICONHEIGHT-100),(WINDOWHEIGHT-230))
self.artistlabel.move((PLAYICONHEIGHT-100),(WINDOWHEIGHT-220))
self.albumlabel.move((PLAYICONHEIGHT-100),(WINDOWHEIGHT-250))
into the __init__(self) method and keep only the labels updating code in your updateTrackInfo method
I would suggest to use currentIndexChanged QComboBox signal instead of activated
Related
I created different tabs using QTableWidget in a loop:
self.table_widget = QTableWidget()
for i in range(0, 5):
self.table_widget.tab = QWidget()
self.table_widget.tabs.addTab(self.table_widget.tab, f"{i}")
self.table_widget.tab.Layout = QVBoxLayout(self)
self.tab_table = QTableWidget(self)
self.table_widget.tab.Layout.addWidget(self.tab_table)
self.table_widget.tab.setLayout(self.table_widget.tab.Layout)
self.table_widget.show()
How can I access the QTableWidget inside the different tabs? Each tab does not have a specific variable name, which can be used to control the widget. I can get the currentIndex of the tab, but I don't know how to use this information.
The simple solution is to create a list as an instance attribute, and add the table widgets to it. Note that there's no point in setting instance attributes in a loop, as they will be overwritten every time.
Also, you should not create a layout with a widget argument if you're going to set that layout to another widget.
self.tables = []
for i in range(5):
tab = QWidget()
self.table_widget.tabs.addTab(tab, f"{i}")
layout = QVBoxLayout(tab)
tab_table = QTableWidget()
layout.addWidget(tab_table)
self.tables.append(tab_table)
Alternatively, you can make the table an instance member of the page:
for i in range(5):
tab = QWidget()
self.table_widget.tabs.addTab(tab, f"{i}")
layout = QVBoxLayout(tab)
tab.tab_table = QTableWidget()
layout.addWidget(tab.tab_table)
def get_table(self, index):
tab = self.table_widget.tabs.widget(index)
return tab.tab_table
Another possibility, as long as it's guaranteed that each tab only has one table, is to use findChild():
def get_table(self, index):
tab = self.table_widget.tabs.widget(index)
return tab.findChild(QTableWidget)
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 initUIininit`, 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!
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.
I have a window showing a tree view of multiple records fetched from MySql server. I was hoping to show another pop-up window with entries and comboboxes ,and have their default values set by the information of the record that was selected on.
The problem is that it does not display anything instead the boxes are left with blanks
I have tried to set the textvariable=var.get(), but this makes the combobox unable to change values and collect the users' input.
I have also tried to use a class:
class Application:
def __init__(self, parent, vars, pos_x, pos_y, to_test, width):
self.parent = parent
self.vars = vars
self.pos_x = pos_x
self.pos_y = pos_y
self.to_test = to_test
self.width = width
self.combo()
def combo(self):
self.box_value = tk.StringVar()
self.box = ttk.Combobox(self.parent, width=self.width,
textvariable=self.box_value)
self.box['values'] = self.vars
for i in range(len(self.vars)):
if not self.to_test == 'None':
if self.vars[i] == self.to_test:
self.box.current(i)
self.box.place(x=self.pos_x, y=self.pos_y)
#I have the function edit_tree called in a button of a previous window win
#The tree is the tree view displayed in the previous window
def edit_tree(win, tree):
selected = tree.selection()
edit_vendor_window = tk.Toplevel(win)
edit_vendor_window.geometry('600x570')
tk.Label(edit_vendor_window, text='Report Date:').place(x=10, y=10)
vars = ('2018', '2019')
Application(edit_vendor_window, vars, 150, 10, tree.item(selected,
'values)[0], 5)
I saw in some other answers that the problem is StringVar is getting garbage collected, and the solution is to use a class. But it does not work for me. This stuff just drove me crazy. Please help me out.
Your self.vars[i] and self.to_test might not be of the same type, so your for loop never reach the comparison part. Try cast both into Str and also remove the textvariable parameter in your Combobox.
def combo(self):
self.box = ttk.Combobox(self.parent, width=self.width)
self.box['values'] = self.vars
for i in range(len(self.vars)):
if not self.to_test == 'None':
if str(self.vars[i]) == str(self.to_test):
self.box.current(i)
self.box.place(x=self.pos_x, y=self.pos_y)
How to make a list of line editors without many variables? (smth like self.line_1 = QLineEdit(self), self.line_2 = QLineEdit(self), ... , self.line_9000 = QLineEdit(self))
For example, I want to create this
window with ability to get access to each element.
A simple cycle does not provide access to each element, only last. How I can do this?
One way is to make widgets as you said - cycle,
and you can access to the widget with using layout.itemAtPosition
it would go like this :
layout = QVBoxLayout()
for i in range(list_length):
line_edit = QLineEdit(self)
layout.addWidget(line_edit)
to access the widget :
def access_widget(int):
item = layout.itemAtPosition(int)
line_edit = item.widget()
return line_edit
now you can access to the designated QLineEdit.
layout = QFormLayout()
self.alphabet_line_edits = dict.fromkeys(['а', 'б', 'в', 'г'])
for letter in self.alphabet_line_edits:
line_edit = QLineEdit()
layout.addRow(letter, line_edit)
self.alphabet_line_edits[letter] = line_edit
def button_clicked(self):
print(self.alphabet_line_edit['б'].text())
I have a problem desinging a window using PySide.
class MainForm(QWidget):
def __init__(self, parent=None):
super(MainForm, self).__init__()
# init window
self.hbox = QHBoxLayout(self)
self.scroll = QScrollArea(self)
self.table = QTableWidget(self)
self.leftspltr = QSplitter(QtCore.Qt.Vertical)
self.rightspltr = QSplitter(QtCore.Qt.Vertical)
self.scroll.setWidget(self.leftspltr)
self.rightspltr.addWidget(self.table)
self.hbox.addWidget(self.leftspltr)
self.hbox.addWidget(self.rightspltr)
self.setWindowTitle("...")
self.table.setColumnCount(3)
self.table.move(11,220)
self.table.verticalHeader().hide()
self.table.setHorizontalHeaderLabels(["Key","Full","HR"])
dic = dumpered_hash.dict_naming_values
os.popen("rm dumpered_hash dumpered_hash.py dumpered_hash.pyc")
xpos = 0
ypos = 0
for key, val1 in sorted(dic.iteritems()):
btn = QPushButton(key, self)
btn.clicked.connect(partial(self.fillTbl, val1, len(val1) + 1))
btn.setFixedSize(84,20)
self.leftspltr.addWidget(btn)
im trying to design a window that has some button (more than 30) placed virtically, so I want to have them in scroll bar that fits the window size, and a table at the right side that doesnt move while scrolling.
the code above gives me a tiny scroll bar that moves the button, bur they are out of the window size.
what wrong there ?
I think I understand what you are trying to do here. However, you are placing your buttons in a vertical splitter and then fixing their size. Instead, place the buttons in a vertical layout, and then place that and the table widget into a horizontal splitter.
class MainForm(QtGui.QWidget):
def __init__(self, parent=None):
super(MainForm, self).__init__()
# init window
self.hbox = QtGui.QHBoxLayout(self)
self.btnbox = QtGui.QVBoxLayout()
self.scroll = QtGui.QScrollArea(self)
self.table = QtGui.QTableWidget(self)
self.spltr = QtGui.QSplitter(QtCore.Qt.Horizontal)
self.setWindowTitle("...")
self.table.setColumnCount(3)
self.table.move(11,220)
self.table.verticalHeader().hide()
self.table.setHorizontalHeaderLabels(["Key","Full","HR"])
dic = {}
for i in range(30):
dic['foo '+str(i)] = [i]
for key, val1 in sorted(dic.iteritems()):
btn = QtGui.QPushButton(key, self)
self.btnbox.addWidget(btn)
# must place layout into a widget before adding to QScrollArea
holder = QtGui.QWidget()
holder.setLayout(self.btnbox)
self.scroll.setWidget(holder)
self.spltr.addWidget(self.scroll)
self.spltr.addWidget(self.table)
self.hbox.addWidget(self.spltr)
I would also like to note, that is it better to include the simplest piece of code necessary to reproduce your problem. I don't know what you are trying to achieve with the lines containing dumpered_hash, but it seems to be irrelevant, as well as a dubious use of a deprecated function, and makes it impossible to run your code without modification. Make it easier for people to help you!