I'm writing simple calculator by using PyQt. In my code I'm using QGridLayout to compound widgets. But there is a problem. I can't find a way to resize widgets. I tryed to using QWidget.resize and insertStreach, but it's does not work like i need to. Which function can substitute QWidget.resize?
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
class Button(QPushButton):
def __init__(self, text, parent, TextObject):
super().__init__(text, parent=parent or None)
self.clicked.connect(TextObject.SLOT_TextInsert('%s' %(text)))
class Text(QLineEdit):
def __init__(self, parent):
super().__init__(parent=parent)
self.show()
def SLOT_TextInsert(self, text):
return lambda: self.insert('%s' %(text))
def SLOT_TextGet(self):
text = self.text()
if __name__ == '__main__':
app = QApplication(sys.argv)
root = QWidget()
text = Text(root)
plus = Button('+', root, text)
minus = Button('-', root, text)
multiple = Button('*', root, text)
divide = Button('/', root, text)
null = Button('0', root, text)
dot = Button('.', root, text)
equal = Button('=', root, text)
clean = Button('Ce', root, text)
layout = QGridLayout(root)
layout.setSpacing(2)
layout.addWidget(text, 1, 1, 1, 5)
layout.addWidget(plus, 2, 4)
layout.addWidget(minus, 2, 5)
layout.addWidget(multiple, 3, 4)
layout.addWidget(divide, 3, 5)
layout.addWidget(clean, 4, 4, 1, 2)
layout.addWidget(null, 5, 1, 1, 2)
layout.addWidget(dot, 5, 3)
layout.addWidget(equal, 5, 4, 1, 2)
num_list = list()
row=2; col=1
for i in range(0,9):
num_list.append(Button('%s' %(i+1), root, text))
layout.addWidget(num_list[i], row, col )
col = col+1
if i == 2 or i == 5:
col = 1; row = row+1
root.resize(10,10)
root.show()
sys.exit(app.exec_())
See QWidget::sizePolicy:
Button-like widgets set the size policy to specify that they may stretch horizontally, but are fixed vertically.
In order to make the buttons also resize vertically, you need to modify the size policy of your buttons:
class Button(QPushButton):
def __init__(self, text, parent, TextObject):
super().__init__(text, parent=parent or None)
self.setSizePolicy ( QSizePolicy.Expanding, QSizePolicy.Expanding)
self.clicked.connect(TextObject.SLOT_TextInsert('%s' %(text)))
Related
I am struggling to retrieve results from a QDialog window and pass them back to the previous window. I want the user to be able to select a value/values, and then once they click okay in the dialog window, it should return them back to the previous window, and pass the text into the byVariables Textbox. The error returns on the line self.procUnivariate.byVariables.setText(item.text()). The error states:
AttributeError: 'ProcUnivariateVariables' object has no attribute 'procUnivariate'
I also tried using a return statement as you can see that is commented out. Unfortunately it seemed like the code got stuck and wasn't moving to the next line as I threw a print statement after and it never printed that line. I need help figuring out how to pass it back to the ProcUnivariate class once the okay button is clicked. Also, if I can figure this out, I'll likely turn the ProcUnivariate Class into a dialog window as well because it should take away the focus from the main window and shouldn't stay open if the main window is closed.
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QListWidget, QLineEdit, QTextEdit, QGridLayout, QHBoxLayout, QVBoxLayout, QDialog, QSizePolicy, QFileDialog, QTabWidget, QCheckBox
import PyQt5.QtGui as qtg
import glob
import os
from PyQt5.QtCore import Qt, QSettings
import inspect
from PyQt5 import QtCore
import pandas as pd
import pathlib
import pyreadstat
import json
class ProcUnivariateVariables(QDialog):
def __init__(self):
super().__init__()
self.procUnivariateByVariables = []
self.layout = QGridLayout()
self.setLayout(self.layout)
self.allVariables = QListWidget()
self.allVariables.setSelectionMode(3)
self.variablesSelected = QListWidget()
self.variablesSelected.setSelectionMode(3)
self.layout.addWidget(self.allVariables, 1,0, 4, 1)
self.layout.addWidget(self.variablesSelected, 1, 1, 4, 1)
self.okButton = QPushButton("Ok")
self.resetButton = QPushButton("Reset")
self.cancelButton = QPushButton("Cancel")
self.layout.addWidget(self.okButton, 1, 2)
self.layout.addWidget(self.resetButton, 2, 2)
self.layout.addWidget(self.cancelButton, 3, 2)
self.addByVariable = QPushButton(">")
self.removeVariable = QPushButton("<")
self.layout.addWidget(self.addByVariable, 5, 0)
self.layout.addWidget(self.removeVariable, 5, 1)
self.button_Connections()
def setItems(self, items):
self.allVariables.clear()
for item in items:
self.allVariables.addItem(item)
def add_by_variable(self):
selected_elements=[item.text() for item in self.allVariables.selectedItems()]
variableItem = self.variablesSelected.insertItems(self.variablesSelected.count(),selected_elements)
def button_Connections(self):
self.addByVariable.clicked.connect(self.add_by_variable)
self.removeVariable.clicked.connect(self.remove_variable)
self.okButton.clicked.connect(self.okay_clicked)
def remove_variable(self):
removeVariables = [item.text() for item in self.variablesSelected.selectedItems()]
self.selectedVariables.takeItems(removeVariables)
#sourceItem = self.currentSource.takeItem(oldSource)
def okay_clicked(self):
self.byVariablesSelected = [item.text() for item in self.variablesSelected.selectedItems()]
#self.procUnivariateByVariables = byVariablesSelected
print(self.byVariablesSelected)
self.accept()
#return self.byVariablesSelected
for item in self.byVariablesSelected:
print(item)
self.procUnivariate.byVariables.setText(item.text())
class ProcUnivariate(QWidget):
def __init__(self):
super().__init__()
self.procUnivariateVariables = None
layout = QGridLayout(self)
##Proc Univariate window Widgets
self.by = QLabel("By")
self.byVariables = QLineEdit()
self.byVariableList = QListWidget()
self.byButton = QPushButton("...")
self.varLabel = QLabel("Var")
self.classLabel = QLabel("Class")
self.freqLabel = QLabel("Freq")
self.histogramLabel = QLabel("Histogram")
self.freqBox = QLineEdit()
self.histBox = QLineEdit()
self.varBox = QLineEdit()
self.varButton = QPushButton("...")
self.sourceLabel = QLabel("Name")
self.sourceText = QLineEdit()
self.sourceButton = QPushButton("...")
self.selectionLabel = QLabel("Selection criteria")
self.selectionCriteria = QTextEdit()
self.statisticLabel = QLabel("Output")
self.statisticSearch = QLineEdit()
self.statisticList = QListWidget()
self.statisticList.setSortingEnabled(True)
self.outputLabel = QLabel("Output Statement")
self.outputText = QTextEdit()
self.fileOutputPath = QLineEdit("Output File Path")
self.runButton = QPushButton("Run")
self.previewButton = QPushButton("Preview")
self.okButton = QPushButton("Ok")
self.resetButton = QPushButton("Reset")
self.cancelButton = QPushButton("Cancel")
self.secondWindowConnections()
layout.addWidget(self.by, 1,0,1,1)
layout.addWidget(self.byVariables, 2, 0, 1, 4)
layout.addWidget(self.byButton, 2, 5, 1, 1)
#layout.addWidget(self.byVariableList, 3, 0, 1, 1)
layout.addWidget(self.freqLabel, 3, 0)
layout.addWidget(self.freqBox, 4, 0, 1, 4)
layout.addWidget(self.histogramLabel, 5, 0)
layout.addWidget(self.histBox, 6, 0, 1, 4)
layout.addWidget(self.varLabel, 7, 0, 1, 4)
layout.addWidget(self.varBox, 8, 0)
layout.addWidget(self.varButton, 8,5)
layout.addWidget(self.sourceLabel, 1, 6)
layout.addWidget(self.sourceText, 2, 6, 1, 4)
layout.addWidget(self.sourceButton, 2, 10)
layout.addWidget(self.selectionLabel, 3, 6)
layout.addWidget(self.selectionCriteria, 4, 6, 1, 4)
layout.addWidget(self.statisticLabel, 5, 6)
layout.addWidget(self.statisticSearch, 6, 6, 1, 4)
layout.addWidget(self.statisticList, 7, 6, 3, 4)
layout.addWidget(self.outputLabel, 10, 6)
layout.addWidget(self.outputText, 11, 6, 1, 4)
layout.addWidget(self.runButton, 12, 6)
layout.addWidget(self.previewButton, 12, 7)
layout.addWidget(self.okButton, 12, 8)
layout.addWidget(self.resetButton, 12, 9)
layout.addWidget(self.cancelButton, 12, 10)
self.setLayout(layout)
def secondWindowConnections(self): # this had a typo
self.byButton.clicked.connect(self.show_third_window)
def show_third_window(self):
if self.procUnivariateVariables is None: # if window has been created yet
self.procUnivariateVariables = ProcUnivariateVariables() # create window
if not self.procUnivariateVariables.isVisible(): # if window is showing
self.procUnivariateVariables.show() # show window
self.procUnivariateVariables.setItems(self.procUnivariateVariablesItems) # send items to window
def send_items(self, items): # this is to collect the variable that
self.procUnivariateVariablesItems = items # move to the third window
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# Add a title
self.setWindowTitle("GUI Querying Program")
self.layout = QHBoxLayout()
self.setLayout(self.layout)
self.initUI()
self.setButtonConnections()
self.sw = None # dont initialize until neccessary.
def initUI(self):
subLayouts = {}
subLayouts['LeftColumn'] = QGridLayout()
self.layout.addLayout(subLayouts['LeftColumn'],1)
self.buttons = {}
self.buttons['addVariable'] = QPushButton('>')
self.buttons['removeVariable'] = QPushButton('<')
self.buttons['Toolkit'] = QPushButton('Toolkit')
self.variables = QListWidget()
self.selectedVariables = QListWidget()
subLayouts['LeftColumn'].addWidget(self.variables, 7,0,4,1)
subLayouts['LeftColumn'].addWidget(self.selectedVariables, 7,1,4,1)
subLayouts['LeftColumn'].addWidget(self.buttons['addVariable'], 10,0,1,1)
subLayouts['LeftColumn'].addWidget(self.buttons['removeVariable'], 10,1,1,1)
subLayouts['LeftColumn'].addWidget(self.buttons['Toolkit'], 11,1,1,1)
names = ['apple', 'banana', 'Cherry']
self.variables.insertItems(0, names)
def setButtonConnections(self):
self.buttons['addVariable'].clicked.connect(self.add_variable)
self.buttons['Toolkit'].clicked.connect(self.show_new_window)
# self.buttons['Toolkit'].clicked.connect(self.add_selected_variables)
# only use one connnect slot
def add_variable(self):
for item in self.variables.selectedItems():
self.selectedVariables.addItem(item.clone())
def show_new_window(self):
if self.sw is None: # check if window has been constructed
self.sw = ProcUnivariate() # construct window
if not self.sw.isVisible(): # If winow is not showing
self.sw.show() # show window
self.sw.send_items(self.add_selected_variables()) # send selected
# variables to second window
def add_selected_variables(self):
items = []
for i in range(self.selectedVariables.count()):
items.append(self.selectedVariables.item(i).clone())
# self.tw.setItems(items) ... self.tw doesnt exist so return them
return items
if __name__ == "__main__":
import sys
app = QApplication([])
mw = MainWindow()
mw.show()
app.exec()
What you need to do is connect a slot to the accepted signal of the dialog, and then retrieve the variables via a dedicated method of the dialog when that signal is emitted.
Here are all the relevant changes (fully tested as working):
class ProcUnivariateVariables(QDialog):
...
def button_Connections(self):
...
# connect to the dialog's built-in accept slot
self.okButton.clicked.connect(self.accept)
# add a method for retrieving the variables
def byVariablesSelected(self):
return [item.text() for item in self.variablesSelected.selectedItems()]
class ProcUnivariate(QWidget):
...
def secondWindowConnections(self): # this had a typo
self.byButton.clicked.connect(self.show_third_window)
self.varButton.clicked.connect(self.show_third_window)
def show_third_window(self):
if self.procUnivariateVariables is None: # if window has been created yet
self.procUnivariateVariables = ProcUnivariateVariables() # create window
# connect the new slot to the dialog's built-in accepted signal
self.procUnivariateVariables.accepted.connect(self.receive_selected_variables)
if not self.procUnivariateVariables.isVisible(): # if window is showing
self.procUnivariateVariables.show() # show window
self.procUnivariateVariables.setItems(self.procUnivariateVariablesItems) # send items to window
# set an identifier from the source button
self.procUnivariateVariables.sourceName = self.sender().text()
# add a slot for handling the dialog's accepted signal
def receive_selected_variables(self):
variables = self.procUnivariateVariables.byVariablesSelected()
text = ', '.join(variables)
if self.procUnivariateVariables.sourceName == 'byButton':
self.byVariables.setText(text)
else:
self.varBox.setText(text)
(Note that the above changes make the okay_clicked method of ProcUnivariateVariables redundant, so it should be removed).
Within my QApplication I want to create QListWidgets dynamically and do something with listitems.
I want to create a Favorite Tab. The only think that work is self.listWidget_fav.clear
There are 4 QPushButtons
the self.buttonOK button have to use the list items
the self.buttonRemoveFav has to remove the entire QListWidget with the 4 QPushButtons
the self.buttonDel has to clear the entire list <---- working
the self.buttonDelSel has to remove selected listItem.
What's wrong?
import sys, time, names
from PyQt5 import QtCore
from PyQt5.QtCore import QAbstractTableModel, Qt
from PyQt5.QtWidgets import *
from functools import partial
import names
colPos = 0
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.resize(800, 600)
self.tabs = QTabWidget()
self.tabs.layout = QGridLayout()
self.tabs.setLayout(self.tabs.layout)
self.grid = QGridLayout()
self.grid.addWidget(self.tabs)
self.setLayout(self.grid)
self.setCentralWidget(self.tabs)
self.result = QTabWidget()
self.result.layout = QGridLayout()
self.result.setLayout(self.result.layout)
self.fav = QTabWidget()
self.fav.layout = QGridLayout()
self.fav.setLayout(self.fav.layout)
self.tabs.addTab(self.result, 'Tab 1')
self.tabs.addTab(self.fav, 'Fav')
#create space to put the export button in the bottom of the TableView
positions = [(i,j) for i in range(20) for j in range(10)]
lst = []
for i in range(30):
lst.append(names.get_full_name())
print(lst)
self.checkBoxes = []
for position, no in zip(positions, lst):
self.checkB = QCheckBox(str(no), self)
self.result.layout.addWidget(self.checkB, *position)
self.checkBoxes.append(self.checkB)
#select All
self.buttonSelAll = QPushButton("Select All", self)
self.buttonSelAll.clicked.connect(partial(self.selectBoxes, True))
self.result.layout.addWidget(self.buttonSelAll, 21, 0)
#select All
self.buttonNone = QPushButton("Select None", self)
self.buttonNone.clicked.connect(partial(self.selectBoxes, False))
self.result.layout.addWidget(self.buttonNone, 21, 1)
#select All
self.buttonFav = QPushButton("Fav", self)
self.buttonFav.clicked.connect(self.toFav)
self.result.layout.addWidget(self.buttonFav, 21, 3)
self.checkBtext = [] # var for text of checkboxes.
for i in range(len(self.checkBoxes)):
self.checkBtext.append(self.checkBoxes[i].text())
self.res = {}
def resetColPos(self):
global colPos
colPos = colPos - 2
self.listWidget_fav.hide()
self.buttonOK.hide()
self.buttonDel.hide()
self.buttonDelSel.hide()
self.buttonRemoveFav.hide()
def removeSelfromFav(self):
listItems = self.listWidget_fav.selectedItems()
if not listItems: return
for item in listItems:
self.listWidget_fav.takeItem(self.listWidget_fav.row(item))
def toFav(self):
global colPos
states = [c.isChecked() for c in self.checkBoxes]
self.selectedChecktext = [] #Text of selected checkbox
for key in self.checkBtext:
for value in states:
self.res[key] = value
states.remove(value)
break
print("self.res.items(): ", self.res.items())
print(len(self.res))
for k, v in self.res.items():
if v == True and not k in self.selectedChecktext:
self.selectedChecktext.append(k)
elif v == False and k in self.selectedChecktext:
self.selectedChecktext.remove(k)
print("self.selectedChecktext: ", self.selectedChecktext)
self.listWidget_fav = QListWidget()
self.listWidget_fav.addItems(self.selectedChecktext)
self.fav.layout.addWidget(self.listWidget_fav, 0, colPos, 5, 2)
self.fav.setLayout(self.fav.layout)
self.buttonOK = QPushButton("ok", self)
self.fav.layout.addWidget(self.buttonOK, 6, colPos)
self.fav.setLayout(self.fav.layout)
self.buttonRemoveFav = QPushButton("Remove Fav", self)
self.buttonRemoveFav.clicked.connect(self.resetColPos)
self.fav.layout.addWidget(self.buttonRemoveFav, 6, colPos+1)
self.fav.setLayout(self.fav.layout)
self.buttonDel = QPushButton("Clear List", self)
self.buttonDel.clicked.connect(self.listWidget_fav.clear)
self.fav.layout.addWidget(self.buttonDel, 7, colPos)
self.fav.setLayout(self.fav.layout)
self.buttonDelSel = QPushButton("Delete selected", self)
self.fav.layout.addWidget(self.buttonDelSel, 7, colPos+1)
self.fav.setLayout(self.fav.layout)
colPos = colPos + 2
def checkStates(self):
states = [c.isChecked() for c in self.checkBoxes]
print ("states: ", states)
def selectBoxes(self, state):
for check in self.checkBoxes:
check.blockSignals(True)
check.setChecked(state)
check.blockSignals(False)
self.checkStates()
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyle('Fusion')
mw = MainWindow()
mw.show()
sys.exit(app.exec_())
names Package have to be installed via pip -m install names ;)
So the below code is part of a bigger project but in general, I have a QTableWidget which is populated from a database. One of the items is a combobox which when the user selects a milestone option from the combobox I want to be able to know which row and column the combo box that was select is in so I can then apply a fixed rate to the value of a cell in the same row. All I need help on is how to track which cell (row, column) the combo box that was selected is in.
Please note im using other tabs that are not shown and is why my code is setup the way it is. I found some other help but am not a very experience python programmer so I got stuck.
#!/usr/local/bin/python
# -*- coding: latin9 -*-
import sys, os , random
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import pyqtSlot,SIGNAL,SLOT
import time
import json
import openpyxl
import Lists
class CashflowTab(QtGui.QDialog):
'''
Parent for all tab widgets of the REPO GUI
'''
def __init__(self, parent = None):
super(CashflowTab, self).__init__()
if parent != None:
self.setParent(parent)
self.initUI()
self.loadSettings()
def loadSettings(self):
'''
read settings and read db
'''
fh = open('settings.json')
self.settings = json.load(fh)
fh.close()
#load db
dbpath = self.settings['dbpath']
self.db = Lists.SQLiteHandler(dbpath)
self.repo = Lists.WCNList('ROSQL')
try:
self.db.read(self.repo)
except:
pass
class WCNSelectTab(CashflowTab):
'''
Window for WCN selection
'''
def __init__(self, parent = None):
super(WCNSelectTab, self).__init__(parent)
if parent != None:
self.setParent(parent)
def initUI(self):
global wbsitem, WCNSelectTab_object, linequerycheck
linequerycheck = 'False'
wbsitem = 'null'
QtGui.QApplication.setStyle(QtGui.QStyleFactory.create("cleanlooks"))
gbox = QtGui.QGridLayout(self)
self.projectlist = QtGui.QTableWidget()
self.projectlist.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
#self.projectlist.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
self.projectlist.setColumnCount(3)
self.projectlist.setHorizontalHeaderLabels(QtCore.QStringList(['WBS','Service','Milestone']))
self.projectlist.setColumnWidth(0, 100)
self.projectlist.setColumnWidth(1, 100)
self.projectlist.setColumnWidth(2, 150)
gbox.addWidget(self.projectlist,5,0,3,6)
self.getAwardBudget()
def getAwardBudget(self):
global wbs_details
wbs_details = []
wbs_details.append(["123", "Service 1"])
wbs_details.append(["456", "Service 2"])
print wbs_details
self.projectlist.setRowCount(len(wbs_details))
for n,item in enumerate(wbs_details):
qitem = QtGui.QTableWidgetItem(item[0])
self.projectlist.setItem(n, 0, qitem)
qitem = QtGui.QTableWidgetItem(item[1])
self.projectlist.setItem(n, 1, qitem)
milestone_options = ["Award","Mobilization","Survey"]
milestonecombo = QtGui.QComboBox()
for t in milestone_options:
milestonecombo.addItem(t)
milestonecombo.setFixedWidth(150)
self.projectlist.setCellWidget(n, 2, milestonecombo)
class RepoGUI(QtGui.QMainWindow):
'''
Main Widget for REPO helper
'''
def __init__(self):
super(RepoGUI, self).__init__()
#self.mode = mode
self.initUI()
def initUI(self):
global approval, approval_names, username, approval_names
self.tabs = QtGui.QTabWidget()
self.setCentralWidget(self.tabs)
self.tabs.setAutoFillBackground(1)
fh = open('settings.json')
settings = json.load(fh)
fh.close()
if settings['WCNsubmit'] == 1:
self.tabs.addTab(WCNSelectTab(), 'WCN Creation')
self.setWindowTitle('Work Completion Notification')
self.setGeometry(300, 150, 1400, 800)
self.setStyleSheet('font-size: %ipt' %settings['fontsize'])
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = RepoGUI()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
A possible solution is to use indexAt() since the position of the QComboBox is relative to the viewport(), but to obtain the QComboBox that was selected we use sender().
for n,item in enumerate(wbs_details):
qitem = QtGui.QTableWidgetItem(item[0])
self.projectlist.setItem(n, 0, qitem)
qitem = QtGui.QTableWidgetItem(item[1])
self.projectlist.setItem(n, 1, qitem)
milestone_options = ["Award","Mobilization","Survey"]
milestonecombo = QtGui.QComboBox()
milestonecombo.addItems(milestone_options)
milestonecombo.setFixedWidth(150)
milestonecombo.currentIndexChanged[str].connect(self.onCurrentIndexChanged)
self.projectlist.setCellWidget(n, 2, milestonecombo)
def onCurrentIndexChanged(self, text):
combobox = self.sender()
ix = self.projectlist.indexAt(combobox.pos())
print(ix.row(), ix.column(), text)
Another possible solution is to use the property:
for n,item in enumerate(wbs_details):
qitem = QtGui.QTableWidgetItem(item[0])
self.projectlist.setItem(n, 0, qitem)
qitem = QtGui.QTableWidgetItem(item[1])
self.projectlist.setItem(n, 1, qitem)
milestone_options = ["Award","Mobilization","Survey"]
milestonecombo = QtGui.QComboBox()
milestonecombo.addItems(milestone_options)
milestonecombo.setFixedWidth(150)
milestonecombo.setProperty("row", n)
milestonecombo.setProperty("column", 1)
milestonecombo.currentIndexChanged[str].connect(self.onCurrentIndexChanged)
self.projectlist.setCellWidget(n, 2, milestonecombo)
def onCurrentIndexChanged(self, text):
combobox = self.sender()
r = combobox.property("row").toPyObject()
c = combobox.property("column").toPyObject()
print(r, c, text)
I have created a custom matplotlib toolbar, and I'm working on the functions associated with the custom toolbar's buttons. One of the buttons functions will (eventually) return a list position that best represents a user's selected position from a plot. I was having a bit of difficulty making this work in my mind, so I made a simple example (trying to avoid using globals) where a label not associated with the toolbar is updated when the toolbar button is pressed.
class TrackPlotToolbar(NavigationToolbar2TkAgg):
toolitems = [t for t in NavigationToolbar2TkAgg.toolitems if
t[0] in ('Home', 'Pan', 'Zoom', 'Save')]
toolitems.append(('Trace', 'Trace Track Position', 'Trace', 'Trace_old'))
def __init__(self, plotCanvas, frame):
self.TraceListOld = []
self.TraceListNew = []
NavigationToolbar2TkAgg.__init__(self, plotCanvas, frame)
def set_message(self, msg):
pass
def Trace_old(self):
gui.infoLabel.text = "abrakadabra"
gui.infoLabel.update()
return 1
class gui(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.grid()
self.parent = parent
self.infoLabel = Label(master = self, text = 'magic')
self.initUI()
def initUI(self):
TestPlot = FigureCanvasTkAgg(TestFig, self)
TestPlot.get_tk_widget().grid(column = 0,\
row = 0, columnspan = 3, rowspan = 5)
TestFrame = Frame(self)
TestFrame.grid(column = 2, row =6, columnspan = 3)
shockToolbar = TrackPlotToolbar(TestPlot,TestFrame)
shockToolbar.update()
self.infoLabel.grid(column = 2, row = 7)
def main():
root = Tk()
app = gui(root)
root.mainloop()
if __name__ == '__main__':
main()
Am I taking the wrong approach? Is it possible to inquire for new data on an event associated with a class inside of the parent class?
I'm trying to update a label in a python tkinter application when another widget is selected.
I created a small tool, that demonstrates the issue. The tool will create a small GUI with a label on top. This label should show the number of the box that was selected.
Problem is that when a box number is selected by a mouse click, the number is not shown in the top label. Clicking the box number should call setSelected, which should call app.setLabel(string). However, I get the error "global name 'app' is not defined"
How do I make the object 'app' global?
#!/usr/bin/env python
import Tkinter
def setSelected(string):
app.setLabel(string)
class Gui():
Boxes = []
def __init__(self):
self._root = Tkinter.Tk()
self._root.protocol("WM_DELETE_WINDOW", self._applicationExit)
self._string = Tkinter.StringVar()
self.setLabel('None')
self._label = Tkinter.Label(self._root, textvariable = self._string,
width = 10)
self._label.grid(row = 0, column = 0, padx = 5, pady = 5)
self._createBoxOverview()
self._root.mainloop()
def _applicationExit(self, event = None):
self._root.destroy()
def _createBoxOverview(self):
_frame = Tkinter.LabelFrame(self._root, text = 'Boxes')
for _id in range(4):
self.Boxes.append(Box(_frame, _id))
self.Boxes[_id].grid(row = 0, column = _id)
_frame.grid(row = 1, column = 0, padx = 5, pady = 5)
def setLabel(self, string):
self._string.set(string)
class Box(Tkinter.Label):
def __init__(self, master, id):
Tkinter.Label.__init__(self, master)
self._id = str(id)
self._text = Tkinter.StringVar()
self._text.set(self._id)
self.config(textvariable = self._text, width = 3)
self.bind("<Button-1>", self._onSelect)
def _onSelect(self, event):
setSelected(self._id)
if __name__ == '__main__':
app = Gui()
The issue is that you are creating root (Tk() App) and calling root.mainloop() , inside __init__() itself, so app does not completely get created, since it would only get created if you return from __init__() , but you do not do that until you close the app.
The easiest solution for your case would be to move the root object outisde Gui() class. Example -
import Tkinter
def setSelected(string):
app.setLabel(string)
class Gui():
Boxes = []
def __init__(self, root):
self._root = root
self._root.protocol("WM_DELETE_WINDOW", self._applicationExit)
self._string = Tkinter.StringVar()
self.setLabel('None')
self._label = Tkinter.Label(self._root, textvariable = self._string,
width = 10)
self._label.grid(row = 0, column = 0, padx = 5, pady = 5)
self._createBoxOverview()
def _applicationExit(self, event = None):
self._root.destroy()
def _createBoxOverview(self):
_frame = Tkinter.LabelFrame(self._root, text = 'Boxes')
for _id in range(4):
self.Boxes.append(Box(_frame, _id))
self.Boxes[_id].grid(row = 0, column = _id)
_frame.grid(row = 1, column = 0, padx = 5, pady = 5)
def setLabel(self, string):
self._string.set(string)
class Box(Tkinter.Label):
def __init__(self, master, id):
Tkinter.Label.__init__(self, master)
self._id = str(id)
self._text = Tkinter.StringVar()
self._text.set(self._id)
self.config(textvariable = self._text, width = 3)
self.bind("<Button-1>", self._onSelect)
def _onSelect(self, event):
setSelected(self._id)
if __name__ == '__main__':
root = Tkinter.Tk()
app = Gui(root)
root.mainloop()