I have tried StringVar, I've tried set().
Note: The program successfully calculates the value and returns the answer in a seperate pop-up, but I would like it to display the answer in the readonly "yards" entry field as well.
import tkinter as tk
import tkinter.ttk as ttk
#Formats all of the visible elements of the tkninter GUI.Connects the buttons to their functions.
class MetersToYardsApp:
def __init__(self, parent):
topLevel = ttk.Frame(parent, padding=10)
topLevel.grid(column=0, row=0)
headerLabel = ttk.Label(topLevel, text="Meters to Yards Calculator", font="{Arial} 16 {bold}")
headerLabel.grid(column=0, row=0, sticky="nsew")
inputFrame = ttk.Frame(topLevel, padding=10)
inputFrame.grid(column=0, row=1, sticky="nsew")
metersLabel = ttk.Label(inputFrame, text="Meters:")
yardsLabel = ttk.Label(inputFrame, text="Yards:")
metersEntry = ttk.Entry(inputFrame)
yardsEntry = ttk.Entry(inputFrame, state="readonly")
metersLabel.grid(column=0, row=0, sticky="e")
yardsLabel.grid(column=0, row=1, sticky="e")
metersEntry.grid(column=1, row=0, pady=3)
yardsEntry.grid(column=1, row=1, pady=3)
buttonFrame = ttk.Frame(topLevel)
buttonFrame.grid(column=0, row=2, sticky='nsew')
clearButton = ttk.Button(buttonFrame, text="Clear", command=self.clear)
okayButton = ttk.Button(buttonFrame, text="Calculate", command=self.calculate)
clearButton.grid(column=0, row=0, padx=3)
okayButton.grid(column=1, row=0)
self.mainWindow = topLevel
self.metersEntry = metersEntry
self.yardsEntry = yardsEntry
#Clear Button
def clear(self):
# print("Clear")
self.metersEntry.delete(0, tk.END)
#Formats the Pop-up that displays the answer
def showAnswer(self, parent, text):
rootFrame = ttk.Frame(parent, padding=10)
rootFrame.grid(column=0, row=0)
headerLabel = ttk.Label(rootFrame, text="The Answer", font="{Arial} 14 {bold}")
headerLabel.grid(column=0, row=0)
answerLabel = ttk.Label(rootFrame, text=text, justify=tk.CENTER)
answerLabel.grid(column=0, row=1)
#Performs Calculations if input is valid.
def calculate(self):
# print("Calculate Meters: ", self.metersEntry.get())
try:
meters = float(self.metersEntry.get())
yards = meters * 1.094
except:
top2 = tk.Toplevel(self.mainWindow)
self.showAnswer(top2, "There was an Error.\n" + "Please Enter a Valid Number for Meters")
# print("Please Enter a Valid Number for Meters.")
return
print(meters, "Meters is ", yards, "Yards. ")
top2 = tk.Toplevel(self.mainWindow)
self.showAnswer(top2, str(meters) + " Meters is equivalent to " + "{:.2f} Yards.".format(yards))
return float(yards)
You do have to use DoubleVar to update the Entry element:
yards_entry_var = tk.DoubleVar(inputFrame, 0)
Then you should place it inside the Entry element 'textvariable':
yardsEntry = ttk.Entry(inputFrame, textvariable=yards_entry_var, state="readonly")
to use it outside the init function:
self.yards_entry_var = yards_entry_var
in the calculate function, after calculating the yards:
self.yards_entry_var.set(yards)
And finally, when you want to clear the value in the clear function:
self.yards_entry_var.set(0)
Related
for one of my first little projects I coded a fitnesscalculator last evening. Which has 3 functionalities at the start: Calculating the 1RM, BMI and FFMI. I'm running into the problem of overlapping labels when I first calculate the 1RM and then the FFMI. I have already googled and looked for similar threads but I couldn't find an answer to my solutions as my Gui is and its functionalities are based around a combobox. Please excuse the rather messy code, but I have already tried several methods to deal with this problem
from tkinter import *
from PIL import Image, ImageTk
from tkinter import ttk
root = Tk()
root.geometry("400x400")
root.title("Fitness Calculator")
#dropdown
Options = ["1RM Calculator", "BMI Calculator", "FFMI Calculator"]
#functions
def picker(input):
global calculate_button
global bf_box
global bf_label
global result_label
global result2_label
global result3_label
calculate_button.destroy()
result_label.pack_forget()
result2_label.destroy()
result3_label.destroy()
bf_label.destroy()
bf_box.destroy()
selected = drop.get() #holt sich wert vom dropdown
####################RM CALCULATOR####################
if selected == Options[0]:
#labels
weight_label = Label(root,text="Enter your training weight here: ", padx=10, pady=10)
weight_label.grid(row=2, column=0, sticky=W)
reps_label = Label(root,text="Enter your repetitions here: ", padx=10)
reps_label.grid(row=3, column=0, sticky=W)
def calculate():
weight = int(weight_box.get())
reps = int(reps_box.get())
one_rm = round(weight*(36/(37-reps)), 2)
#Result
result_label = Label(root, text="Your 1RM is: " + str(one_rm) + " kg")
result_label.grid(row=4)
weight_box.delete(0,END)
reps_box.delete(0,END)
#Entryfields
weight_box = Entry(root)
weight_box.grid(row=2, column=1)
reps_box = Entry(root)
reps_box.grid(row=3, column=1)
#Calculate button
calculate_button = Button(root,text="Calculate",command=calculate, width=16 )
calculate_button.grid(row=4,column=1,pady=10)
####################BMI CALC####################
if selected == Options[1]:
#LABELS
weight_label = Label(root,text="Enter your weight in kg here: ", padx=10, pady=10)
weight_label.grid(row=2, column=0, sticky=W)
height_label = Label(root,text="Enter your height in cm here: ", padx=10)
height_label.grid(row=3, column=0, sticky=W)
#ENTRY BOXES
weight_box = Entry(root)
weight_box.grid(row=2, column=1)
height_box = Entry(root)
height_box.grid(row=3, column=1)
def calculate():
weight = float(weight_box.get())
height = float(height_box.get())/100
bmi = round(weight/(height**2),0)
#Result
result_label = Label(root, text="Your BMI is: " + str(bmi))
result_label.grid(row=4)
weight_box.delete(0,END)
height_box.delete(0,END)
#Calculate button
calculate_button = Button(root,text="Calculate",command=calculate, width=16 )
calculate_button.grid(row=4,column=1,pady=10)
####################FFMI####################
if selected == Options[2]:
calculate_button.destroy()
#LABELS
weight_label = Label(root,text="Enter your weight in kg here: ", padx=10,pady=5)
weight_label.grid(row=2, column=0, sticky=W)
height_label = Label(root,text="Enter your height in cm here: ", padx=10,pady=5)
height_label.grid(row=3, column=0, sticky=W)
bf_label = Label(root,text="Enter your estimated bodyfat % here: ", padx=10,pady=5)
bf_label.grid(row=4, column=0, sticky=W)
#ENTRY BOXES
weight_box = Entry(root)
weight_box.grid(row=2, column=1)
height_box = Entry(root)
height_box.grid(row=3, column=1)
bf_box = Entry(root)
bf_box.grid(row=4, column=1)
def calculate():
weight = float(weight_box.get())
height = float(height_box.get())/100
bf = float(bf_box.get())
total_bf = weight*(bf)
lean_weight = weight*(1-(bf/100))
ffmi = round((lean_weight/height**2),2)
adjusted_ffmi = ffmi + 6.1 * (1.8 - height)
#Result
result_label = Label(root, text="Lean Mass: " + str(lean_weight) + " kg")
result_label.grid(row=6, sticky=W, padx=5)
result_label2 = Label(root, text="FFMI: " + str(ffmi))
result_label2.grid(row=7, sticky=W, padx=5)
result_label3 = Label(root, text="adjusted-FFMI: " + str(adjusted_ffmi))
result_label3.grid(row=8,sticky=W, padx=5)
weight_box.delete(0,END)
height_box.delete(0,END)
bf_box.delete(0,END)
#Calculate button
calculate_button = Button(root,text="Calculate",command=calculate, width=16 )
calculate_button.grid(row=5,column=1,pady=10)
calculate_button = Button(root,text="Calculate", width=16 )
calculate_button.grid(row=4,column=1,pady=10)
calculate_button.destroy()
#Dropdownbox
drop = ttk.Combobox(root, value=Options, state="readonly")
drop.current(0)
drop.grid(row=0)
drop.bind("<<ComboboxSelected>>", picker)
result_label = Label(root,text="test")
result_label.grid(row=4)
result2_label = Label(root,text="")
result2_label.grid(row=4)
result3_label = Label(root,text="")
result3_label.grid(row=4)
bf_label = Label(root)
bf_box = Entry(root)
picker(drop.current(0))
root.mainloop()
Here a Screenshot of the problem I'm referencing to:
You keep creating a new Label with name result_label in your calculate methods.
This piles the labels on top of each other, since the result_label.destroy() does not remove them from the grid.
Instead of destroying them, keep just one instance (which you already defined global) and then configure them with the new text:
result_label.config(text="Your BMI is: " + str(bmi))
So the issue is when I click the calc_button, which calls the calculate_tip method, I get a NameError saying 'subtotal_entry' is not defined. I have tried a bunch of different things to get this working but nothing has worked so far. I am trying to get the users input from the Entry I created called subtotal_entry.
Here is my code:
from tkinter import *
from tkinter import messagebox
class TipGUI:
def __init__(self,master):
self.master = master
master.title('Tip Calculator')
#create the frames
subtotal_frame = Frame(master).grid(row=0, column=0)
percent_frame = Frame(master).grid(row=1, column=0)
tip_frame = Frame(master).grid(row=2, column=0)
button_frame = Frame(master).grid(row=3, column=0)
total_frame = Frame(master).grid(row=4, column=0)
#create the labels
subtotal_label = Label(subtotal_frame, text="Enter the amount of the ticket:").grid(row=0, column=0)
percent_label = Label(percent_frame, text="Enter the tip as a percent:").grid(row=1, column=0)
tip_label = Label(tip_frame, text="Tip Amount: $").grid(row=2, column=0)
tipAmt_label = Label(tip_frame, text="").grid(row=2, column=1)
total_label = Label(total_frame, text="Total Amount: $").grid(row=3, column=0)
totalAmt_label = Label(total_frame, text="").grid(row=3, column=1)
#create entry boxes
subtotal_entry = Entry(subtotal_frame).grid(row=0, column=1)
percent_entry = Entry(percent_frame).grid(row=1, column=1)
#create buttons
calc_button = Button(button_frame, text="Calculate", command= self.calculate_tip).grid(row=4, column=0)
exit_button = Button(button_frame, text="exit", command= master.quit).grid(row=4, column=1)
def calculate_tip(self):
subtotal = Entry.get(subtotal_entry)
percent = percent_entry.get()
if subtotal <= 0:
messagebox.showinfo("Error","Please enter a subtotal greater than 0")
if percent <= 0:
messagebox.showinfo("Error","Please enter a tip percentage greater than 0")
else:
tip = subtotal * percent
total = tip + subtotal
tipAmt_label.config(text = format(tip, ',.2f'))
totalAmt_label.config(text = format(total, ',.2f'))
subtotal_entry.delete(0, END)
percent_entry.delete(0,END)
#Create the window
window = Tk()
tipGUI = TipGUI(window)
window.mainloop()
You have few common problems.
subtotal_entry is local variable which can't be accessed in other functions. You have to use self.subtotal_entry to create variable which can be accessed in other functions in class.
variable = Widget.grid() assigns None to variable because grid(), pack(), place() returns None. You have to do it in two steps
variable = Widget()
variable.grid()
And if later you don't have to access some widget (some Labels) then you can skip variable
Widget().grid()
To get value you need subtotal_entry.get() instead of Entry.get(subtotal_entry)
Entry gives string so you have to use int() or float() to convert string to value.
Full working code.
I assumed that percent will be value 0 ... 100, not 0.00 ... 1.00
I removed most of Frames because they were useless.
import tkinter as tk # PEP8: `import *` is not preferred
from tkinter import messagebox
class TipGUI:
def __init__(self, master):
self.master = master
master.title('Tip Calculator')
#create the labels
subtotal_label = tk.Label(master, text="Enter the amount of the ticket:")
subtotal_label.grid(row=0, column=0, stick='e')
percent_label = tk.Label(master, text="Enter the tip as a percent:")
percent_label.grid(row=1, column=0, stick='e')
self.tip_label = tk.Label(master, text="Tip Amount: $")
self.tip_label.grid(row=2, column=0, columnspan=2)
self.total_label = tk.Label(master, text="Total Amount: $")
self.total_label.grid(row=3, column=0, columnspan=2)
#create entry boxes
self.subtotal_entry = tk.Entry(master)
self.subtotal_entry.grid(row=0, column=1)
self.percent_entry = tk.Entry(master)
self.percent_entry.grid(row=1, column=1)
#create buttons
frame_buttons = tk.Frame(master)
frame_buttons.grid(row=4, column=0, columnspan=2)
calc_button = tk.Button(frame_buttons, text="Calculate", command=self.calculate_tip)
calc_button.grid(row=0, column=0)
exit_button = tk.Button(frame_buttons, text="Exit", command=master.quit)
exit_button.grid(row=0, column=1)
def calculate_tip(self):
subtotal = float(self.subtotal_entry.get())
percent = float(self.percent_entry.get()) / 100
if subtotal <= 0:
messagebox.showinfo("Error","Please enter a subtotal greater than 0")
if percent <= 0:
messagebox.showinfo("Error","Please enter a tip percentage greater than 0")
else:
tip = subtotal * percent
total = tip + subtotal
self.tip_label.config(text=f"Tip Amount: ${tip:,.2f}")
self.total_label.config(text=f"Total Amount: ${total:,.2f}")
self.subtotal_entry.delete(0, 'end')
self.percent_entry.delete(0, 'end')
#Create the window
window = tk.Tk()
tipGUI = TipGUI(window)
window.mainloop()
I've made a simple GUI for placing objects in RoboDK via a Python script using Tkinter.
Essentailly, the user selects an object using the btnSelect button, which then updates the entry widgets with its coordinates (x, y, z, then Euler rotation). The user can then edit the entry widgets then select the "Move object" button (or btnMove in the code) to move the object to the new position. However, when selecting an object for the second time, the entry fields cannot be edited without selecting a new object.
from tkinter.constants import DISABLED, NORMAL, CENTER, END
from typing import *
import tkinter as tk
import threading
from robolink import * # RoboDK API
from robodk import * # Robot toolbox
X_MAX = 500
X_MIN = 0
Y_MAX = 300
Y_MIN = -360
ROTZ_MAX = 180
ROTZ_MIN = -180
# Keep track of selected item
obj = None
def main():
rdk = Robolink()
window = buildGUI(rdk)
window.mainloop()
def buildGUI(rdk: Robolink) -> tk.Tk:
window = tk.Tk()
canvas = tk.Canvas(window, width=200)
canvas.grid(columnspan=3, rowspan=14)
# Set the window title (must be unique for the docking to work, try to be creative)
window_title = 'Move object window'
window.title(window_title)
title = tk.Label(window, text="Move Object", font="none 14 bold")
title.grid(columnspan=3, column=0, row=0)
# Delete the window when we close it
window.protocol("WM_DELETE_WINDOW", lambda: onClose(window))
deadspace1 = tk.Label(text="")
deadspace1.grid(columnspan=3, column=0, row=1)
selectText = tk.StringVar()
btnSelect = tk.Button(window, textvariable=selectText, height=2, width=0,
bg="#bbbbbb", fg='white', justify=CENTER)
selectText.set("Select object")
btnSelect.grid(column=1, row=2)
deadspace2 = tk.Label("")
deadspace2.grid(columnspan=3, column=0, row=3)
objName = tk.StringVar()
objLabel = tk.Label(window, textvariable=objName, font="none 12 bold")
objName.set("None Selected")
objLabel.grid(columnspan=3, column=0, row=4)
deadspace2 = tk.Label("")
deadspace2.grid(columnspan=3, column=0, row=5)
# Position options
xLabel = tk.Label(window, text="x: ", font='none 12')
xLabel.grid(column=0, row=6)
xEntry = tk.Entry(window, width=10)
xEntry.grid(columnspan=2, column=1, row=6)
yLabel = tk.Label(window, text="y: ", font='none 12')
yLabel.grid(column=0, row=7)
yEntry = tk.Entry(window, width=10)
yEntry.grid(columnspan=2, column=1, row=7)
zLabel = tk.Label(window, text="z: ", font='none 12')
zLabel.grid(column=0, row=8)
zEntry = tk.Entry(window, width=10)
zEntry.grid(columnspan=2, column=1, row=8)
# Rotation options
rxLabel = tk.Label(window, text="rx: ", font='none 12')
rxLabel.grid(column=0, row=9)
rxEntry = tk.Entry(window, width=10)
rxEntry.grid(columnspan=2, column=1, row=9)
ryLabel = tk.Label(window, text="ry: ", font='none 12')
ryLabel.grid(column=0, row=10)
ryEntry = tk.Entry(window, width=10)
ryEntry.grid(columnspan=2, column=1, row=10)
rzLabel = tk.Label(window, text="rz: ", font='none 12')
rzLabel.grid(column=0, row=11)
rzEntry = tk.Entry(window, width=10)
rzEntry.grid(columnspan=2, column=1, row=11)
entries = [xEntry, yEntry, zEntry, rzEntry, ryEntry, rxEntry]
deadspace3 = tk.Label(text="")
deadspace3.grid(columnspan=3, column=0, row=12)
btnMove = tk.Button(window, text="Move object", height=2, width=0,
bg="#bbbbbb", fg='white', justify=CENTER,
command=lambda: moveObject(entries))
btnMove.grid(column=1, row=13)
selectCallback = lambda: select_item(rdk, selectText, objName, entries)
btnSelect['command'] = selectCallback
EmbedWindow(window_title)
return window
# Close the window
def onClose(window: tk.Tk):
window.destroy()
quit(0)
def select_item(rdk: Robolink, selectText: tk.StringVar, objName: tk.Label,
entries: List[tk.Entry]):
def thread_btnSelect():
selectText.set("Waiting...")
item = rdk.ItemUserPick('Select an item', ITEM_TYPE_OBJECT)
if item.Valid():
global obj
obj = item
objName.set(item.Name())
updateObjectPosition(item, entries)
selectText.set("Select object")
# Prevent RoboDK from freezing
threading.Thread(target=thread_btnSelect).start()
def updateObjectPosition(item: Item, entries: List[tk.Entry]):
pose = item.Pose()
coords = Pose_2_KUKA(pose)
for entry, coord in zip(entries, coords):
entry.delete(0, END)
entry.insert(0, str(coord))
def moveObject(entries: tk.Entry):
global obj
if obj is None:
ShowMessage("No object selected")
return
try:
coords = getCoords(entries)
obj.setPose(KUKA_2_Pose(coords))
except Exception as err:
ShowMessage(str(err))
def getCoords(entries: List[tk.Entry]) -> list:
coords = [0] * 6
for i, entry in enumerate(entries):
coords[i] = float(entry.get())
return coords
if __name__ == "__main__":
main()
Using a tkinter.Variable such as tkinter.DoubleVar with your entries should fix this issue. You can also use tkinter.DoubleSpin for convenience.
x, y, z, rx, ry, rz = Pose_2_TxyzRxyz(item.Pose())
xVar = tk.DoubleVar(value=x)
xEntry = tk.Spinbox(window, textvariable=xVar, format="%.2f", from_=-9999999, to=9999999)
xVal = xVal.get()
I'm creating a frame which has many that are build vertically and I need a scrollbar to make them all visible. To do that I embedded my frame on a canvas.
The problem is that the widgets on the frame require more width that what the canvas provides as shown below
If I don't embed the frame on a canvas, then the widgets take the proper amount of width and are resized properly. I believe that the problem is the the canvas spans across 1 column whereas the widgets in the canvas require more than 2. I used `columnspan=2' on the canvas but the widgets on the embedded frame are still cut; they are just zoomed.
Is there a way to expand the width of the canvas according to the width they frame wants?
Here's an example code
import tkinter as tk
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
from PIL import ImageTk, Image
import os
# Method to make Label(Widget) invisible
def hide_frame(frame):
# This will remove the widget
frame.grid_remove()
# Method to make Label(widget) visible
def show_frame(frame, c, r):
# This will recover the widget
frame.grid(column=c, row=r)
def populate(frame):
'''Put in some fake data'''
for row in range(100):
tk.Label(frame, text="%s" % row, width=3, borderwidth="1",
relief="solid").grid(row=row, column=0)
t="Blah blah blah blah blah blah blah blah %s" %row
tk.Label(frame, text=t).grid(row=row+4, column=1)
#____________________________________________________________________________________________
#This will be the main window
window = tk.Tk()
#window.geometry('1500x1200')
window.attributes('-zoomed', True)
window.title("daq")
frame_main = Frame(window)
frame_main.place(rely=0.10, relx=0.0, relwidth=1.0)
#Create a tabcontrol
tabControl = ttk.Notebook(frame_main)
tabControl.grid(column=0, row=1)
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Digitizer tab
tab_Digitizer = ttk.Frame(tabControl)
tabControl.add(tab_Digitizer, text=' Digitizer ')
digitizer_tab_dummy_label = Label(tab_Digitizer, text="")
digitizer_tab_dummy_label.grid(column=0, row=0)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Channel settings
lbl_channel_registers = Label(tab_Digitizer, text="Channel registers", font='bold')
lbl_channel_registers.grid(column=0, row=3, sticky=W)
frame_channel_registers = Frame(tab_Digitizer)
frame_channel_registers.grid(column=0, row=4)
btn_hide_channel_registers = Button(tab_Digitizer, text="Hide", fg="red", command=lambda: hide_frame(frame_channel_registers) )
btn_hide_channel_registers.grid(column=1, row=3)
btn_show_channel_registers = Button(tab_Digitizer, text="Show", fg="green", command=lambda: show_frame(frame_channel_registers, 0, 4))
btn_show_channel_registers.grid(column=2, row=3)
##Channel settings - PSD
def onFrameConfigure(event):
'''Reset the scroll region to encompass the inner frame'''
canvas.configure(scrollregion=canvas.bbox("all"))
def handle_user_scrolling(event):
canvas.yview_scroll(int(-event.delta/abs(event.delta)), "units")
def handle_scrollbar_scrolling(event):
canvas.configure(scrollregion=canvas.bbox("all"))
lbl_PSD_channel_registers = Label(frame_channel_registers, text="DPP-PSD registers")
lbl_PSD_channel_registers.grid(column=0, row=3, padx=5, sticky=W)
btn_hide_PSD_channel_registers = Button(frame_channel_registers, text="Hide", fg="red", command=lambda: [hide_frame(canvas), hide_frame(myscrollbar)] )
btn_hide_PSD_channel_registers.grid(column=1, row=3)
btn_show_PSD_channel_registers = Button(frame_channel_registers, text="Show", fg="green", command=lambda: [show_frame(canvas, 0, 4), show_frame(myscrollbar, 1, 4)])
btn_show_PSD_channel_registers.grid(column=2, row=3)
canvas = tk.Canvas(frame_channel_registers, borderwidth=1, background="#FF0000")
frame_PSD_channel_registers = Frame(canvas, background="#0000FF")
frame_PSD_channel_registers.grid(column=0, row=0, padx=25, sticky=W)
frame_PSD_channel_registers.bind("<MouseWheel>", handle_user_scrolling)
frame_PSD_channel_registers.bind("<Configure>", handle_scrollbar_scrolling)
myscrollbar=Scrollbar(frame_channel_registers ,orient="vertical", command=canvas.yview)
#canvas.configure(yscrollcommand=myscrollbar.set)
canvas.configure(scrollregion=canvas.bbox("all"))
myscrollbar.grid(column=1, row=4, sticky=NS)
canvas.grid(column=0, row=4, columnspan=3)
#frame_PSD_channel_registers = Frame(canvas, background="#0000FF")
#frame_PSD_channel_registers.grid(column=0, row=0, padx=25, sticky=W)
#frame_PSD_channel_registers.bind("<MouseWheel>", handle_user_scrolling)
#frame_PSD_channel_registers.bind("<Configure>", handle_scrollbar_scrolling)
canvas.create_window((0, 0), window=frame_PSD_channel_registers, anchor="nw")
canvas.configure(yscrollcommand=myscrollbar.set)
###### PSD channels settings
#Short gate
def short_gate_width_selection(event):
print ("Short gate width : " + str( entry_short_gate_width.get() ) + " " + var_short_gate_width_unit.get() )
pass
lbl_short_gate_width = Label(frame_PSD_channel_registers, text="Short gate width")
lbl_short_gate_width.grid(column=0, row=0, padx=25, sticky=W)
var_short_gate_width = IntVar(frame_PSD_channel_registers)
var_short_gate_width.set("15")
entry_short_gate_width = Entry(frame_PSD_channel_registers, width=10, textvariable=var_short_gate_width, exportselection=0)
entry_short_gate_width.grid(column=1, row=0, sticky=W)
opt_short_gate_width = ["samples", "ns"]
var_short_gate_width_unit = StringVar(frame_PSD_channel_registers)
var_short_gate_width_unit.set(opt_short_gate_width[0]) # default value
short_gate_width_unit = OptionMenu(frame_PSD_channel_registers, var_short_gate_width_unit, *opt_short_gate_width, command = short_gate_width_selection)
entry_short_gate_width.bind('<Return>', short_gate_width_selection)
short_gate_width_unit.grid(column=2, row=0, sticky=W)
#Long gate
def long_gate_width_selection(event):
print ("Long gate width : " + str( entry_long_gate_width.get() ) + " " + var_long_gate_width_unit.get() )
pass
lbl_long_gate_width = Label(frame_PSD_channel_registers, text="Long gate width")
lbl_long_gate_width.grid(column=0, row=1, padx=25, sticky=W)
var_long_gate_width = IntVar(frame_PSD_channel_registers)
var_long_gate_width.set("100")
entry_long_gate_width = Entry(frame_PSD_channel_registers, width=10, textvariable=var_long_gate_width, exportselection=0)
entry_long_gate_width.grid(column=1, row=1, sticky=W)
opt_long_gate_width = ["samples", "ns"]
var_long_gate_width_unit = StringVar(frame_PSD_channel_registers)
var_long_gate_width_unit.set(opt_long_gate_width[0]) # default value
long_gate_width_unit = OptionMenu(frame_PSD_channel_registers, var_long_gate_width_unit, *opt_long_gate_width, command = long_gate_width_selection)
entry_long_gate_width.bind('<Return>', long_gate_width_selection)
long_gate_width_unit.grid(column=2, row=1, sticky=W)
#Extras word options
def extras_word_options_selection(event):
if 'Counter' in var_extras_word_options_selection.get():
extras_word_options_step_counter.grid(column=2, row=22, sticky=W)
else:
extras_word_options_step_counter.grid_remove()
print ("Extras word options : " + var_extras_word_options_selection.get() )
pass
def extras_word_options_step_counter_selection(event):
print ("Step for trigger counter : ", var_extras_word_options_step_counter.get() )
pass
lbl_extras_word_options_selection = Label(frame_PSD_channel_registers, text="Extras word options")
lbl_extras_word_options_selection.grid(column=0, row=22, padx=25, sticky=W)
opt_extras_word_options_selection = ["[31:16] = Extended Time Stamp , [15:0] = Baseline * 4",
"[31:16] = Extended Time Stamp , [15:0] = Flags",
"[31:16] = Extended Time Stamp , [15:10] = Flags, [9:0] = Fine Time Stamp",
"[31:16] = Lost Trigger Counter , [15:0] = Total Trigger Counter",
"[31:16] = Positive Zero Crossing, [15:0] = Negative Zero Crossing",
"Fixed value = 0x12345678 (debug use only)."]
var_extras_word_options_selection = StringVar(frame_PSD_channel_registers)
var_extras_word_options_selection.set(opt_extras_word_options_selection[2]) # default value
extras_word_options_selection = OptionMenu(frame_PSD_channel_registers, var_extras_word_options_selection, *opt_extras_word_options_selection, command = extras_word_options_selection)
extras_word_options_selection.grid(column=1, row=22, sticky=W)
#This keeps the window open - has to be at the end
window.mainloop()
I am trying to get the input of what page number the user wants. They should type in a number, and click the submit button. To test it, I just want to print whatever they typed and then close the window. I've been following: http://effbot.org/tkinterbook/entry.htm as a guide, but I am stumped.
Why does
print(temp)
not print out a number to console?
right now it prints out:
<bound method IntVar.get of <tkinter.IntVar object at 0x000001FBC85353C8>>
I've cleaned up the code a little bit:
import sys
from file import *
from page import *
from view import View
import tkinter as tk
from tkinter import *
class ViewGui:
def __init__(self):
#Included in the class, but unrelated to the question:
self._file = File("yankee.txt", 25)
self.pages = self._file.paginate()
self.initial_list = self.pages[0].readpage(self._file.fo)
self.initial_string = ''.join(self.initial_list)
# Create root
self.root = Tk()
self.root.wm_title("yankee.txt - page 1")
# Create frame for buttons
self.bframe = Frame(self.root)
self.bframe.pack(side=BOTTOM, fill=X)
self.tbutton = tk.Button(self.bframe, text="Top", command=lambda a="top": self.clicks(a)).pack(side=LEFT, expand=1, fill=X)
self.bbutton = tk.Button(self.bframe, text="Bottom", command=lambda a="bottom": self.clicks(a)).pack(side=LEFT, expand=1, fill=X)
self.ubutton = tk.Button(self.bframe, text="Up", command=lambda a="up": self.clicks(a)).pack(side=LEFT, expand=1, fill=X)
self.dbutton = tk.Button(self.bframe, text="Down", command=lambda a="down": self.clicks(a)).pack(side=LEFT, expand=1, fill=X)
self.pbutton = tk.Button(self.bframe, text="Page", command=lambda a="page": self.pageclicks()).pack(side=LEFT, expand=1, fill=X)
self.qbutton = tk.Button(self.bframe, text="Quit", command=quit).pack(side=LEFT, expand=1, fill=X)
# Create and pack Text
self.T = Text(self.root, height=35, width=60, wrap=NONE)
self.T.pack(side=TOP, fill=X)
# Create and pack Scrollbar
self.S = Scrollbar(self.root, orient=HORIZONTAL, command=self.T.xview)
self.S.pack(side=BOTTOM, fill=X)
# Attach Text to Scrollbar
self.T.insert('1.0', self.initial_string)
self.T.config(xscrollcommand=self.S.set, state=DISABLED)
self.S.config(command=self.T.xview)
def pageclicks(self):
print("pageClicks is getting called at least...")
pop = Tk()
pop.wm_title("Page Number")
pop.label = Label(pop, text="Enter a Page Number:", width=35)
pop.label.pack(side=TOP)
pop.entrytext = IntVar()
Entry(pop, textvariable=pop.entrytext).pack()
pop.submitbuttontext = StringVar()
Button(pop, text="Submit", command=lambda a=pop: self.submitted(a)).pack(side=LEFT, pady=5, padx=40)
pop.cancelbuttontext = StringVar()
Button(pop, text="Cancel", command=pop.destroy).pack(side=LEFT, pady=5, padx=40)
def submitted(self, a):
print('submitted is getting called')
temp = (a.entrytext.get)
print(temp)
def clicks(self, a):
print("you clicked clicks with the " + a)
self.root.wm_title(self._file.filename + " - Page " + self._file.buttonHandler(a))
if __name__ == "__main__":
vg = ViewGui()
vg.root.mainloop()
When you create a new window you should not use Tk(), you must use tk.Toplevel()
Must change:
pop = Tk()
to
pop = tk.Toplevel()
You should also use get(), not just get. Must change:
temp = (a.entrytext.get)
to
temp = a.entrytext.get()
Code:
def pageclicks(self):
print("pageClicks is getting called at least...")
pop = tk.Toplevel()
pop.wm_title("Page Number")
pop.label = Label(pop, text="Enter a Page Number:", width=35)
pop.label.pack(side=TOP)
pop.entrytext = IntVar()
Entry(pop, textvariable=pop.entrytext).pack()
pop.submitbuttontext = StringVar()
Button(pop, text="Submit", command=lambda a=pop: self.submitted(a)).pack(side=LEFT, pady=5, padx=40)
pop.cancelbuttontext = StringVar()
Button(pop, text="Cancel", command=pop.destroy).pack(side=LEFT, pady=5, padx=40)
def submitted(self, a):
print('submitted is getting called')
temp = a.entrytext.get()
print(temp)
Made changes to these two methods and now it is working.
def pageclicks(self):
print("pageClicks is getting called at least...")
pop = Tk()
pop.wm_title("Page Number")
pop.label = Label(pop, text="Enter a Page Number:", width=35)
pop.label.pack(side=TOP)
pop._entry = Entry(pop)
pop._entry.pack()
pop._entry.focus_set()
Button(pop, text="Submit", command=lambda a=pop: self.submitted(a)).pack(side=LEFT, pady=5, padx=40)
Button(pop, text="Cancel", command=pop.destroy).pack(side=LEFT, pady=5, padx=40)
def submitted(self, _pop):
temp = _pop._entry.get()
print(temp)
_pop.destroy()