Reputation: 3843
I am trying to create a scrollbar and attach it to frame 2. This is the code:
import tkinter as tk
import tkinter.ttk as ttk
import serial.tools.list_ports
#global variable that will hold the COM port
COMPort = 0
#to be used on our canvas
HEIGHT = 700
WIDTH = 800
#hardcoded baud rate
baudRate = 9600
#make our own buffer
#useful for parsing commands
#Serial.readline seems unreliable at times too
serBuffer = ""
ser = 0 #initial value. will chane at 'on_select('
# --- functions ---
#the following two functtions are for the seria port selection, on frame 1
def serial_ports():
return serial.tools.list_ports.comports()
def on_select(event=None):
global COMPort
COMPort = cb.get()
print(COMPort)
# get selection from event
#print("event.widget:", event.widget.get())
# or get selection directly from combobox
#print("comboboxes: ", cb.get())
global ser
ser = Serial(serialPort , baudRate, timeout=0, writeTimeout=0) #ensure non-blocking
def readSerial():
while True:
c = ser.read() # attempt to read a character from Serial
#was anything read?
if len(c) == 0:
break
# get the buffer from outside of this function
global serBuffer
# check if character is a delimeter
if c == '\r':
c = '' # don't want returns. chuck it
if c == '\n':
serBuffer += "\n" # add the newline to the buffer
#add the line to the TOP of the log
log.insert('0.0', serBuffer)
serBuffer = "" # empty the buffer
else:
serBuffer += c # add to the buffer
root.after(10, readSerial) # check serial again soon
# --- functions ---
# --- main ---
root = tk.Tk() #here we create our tkinter window
root.title("Sensor Interface")
#we use canvas as a placeholder, to get our initial screen size (we have defined HEIGHT and WIDTH)
canvas = tk.Canvas(root, height=HEIGHT, width=WIDTH)
canvas.pack()
#we use frames to organize all the widgets in the screen
# --- frame 1 ---
frame1 = tk.Frame(root)
frame1.place(relx=0, rely=0.05, relheight=0.03, relwidth=1, anchor='nw') #we use relheight and relwidth to fill whatever the parent is - in this case- root
label0 = tk.Label(frame1, text="Select the COM port that the device is plugged in: ")
label0.config(font=("TkDefaultFont", 8))
label0.place(relx = 0.1, rely=0.3, relwidth=0.3, relheight=0.5)
cb = ttk.Combobox(frame1, values=serial_ports())
cb.place(relx=0.5, rely=0.5, anchor='center')
# assign function to cmbobox
cb.bind('<<ComboboxSelected>>', on_select)
# --- frame 1 ---
# --- frame 2 ---
frame2 = tk.Frame(root, bg='#80c1ff') #remove color later
frame2.place(relx=0, rely=0.1, relheight=0.07, relwidth=1, anchor='nw')
# make a scrollbar
scrollbar = Scrollbar(frame2)
scrollbar.pack(side=RIGHT, fill=Y)
# make a text box to put the serial output
log = Text ( frame2, width=30, height=30, takefocus=0)
log.pack()
# attach text box to scrollbar
log.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=log.yview)
# --- frame 2 ---
# after initializing serial, an arduino may need a bit of time to reset
root.after(100, readSerial)
root.mainloop() #here we run our app
However, i get this error:
scrollbar = Scrollbar(frame2)
NameError: name 'Scrollbar' is not defined
I don't understand what i am doing wrong...
EDIT: This is my original program that contains many frames.
[![enter image description here][1]][1]
In the big empty sapce, i was hoping to hook up the frame that will display the serial data, with the scrollbar to the right. [1]: https://i.sstatic.net/IOguE.png
Upvotes: 0
Views: 49
Reputation: 7680
You shouldn't use more than 1 geometry manager in a single tkinter window/frame. Also you don't need to use a <tkinter.Canvas>
to reserve space for your window. The is the <tkinter.Tk>.geometry(...)
method for that.
I think that this is the GUI stuff that you wanted:
# --- main ---
root = tk.Tk() #here we create our tkinter window
root.title("Sensor Interface")
# Set the initial screen size
root.geometry("%ix%i" % (WIDTH, HEIGHT))
#we use frames to organize all the widgets in the screen
# --- frame 1 ---
frame1 = tk.Frame(root)
frame1.pack(side="top")
label0 = tk.Label(frame1, text="Select the COM port that the device is plugged in: ", font=("TkDefaultFont", 8))
label0.grid(row=1, column=1)
cb = ttk.Combobox(frame1, values=serial_ports())
cb.grid(row=1, column=2)
# assign function to cmbobox
cb.bind('<<ComboboxSelected>>', on_select)
# --- frame 1 ---
# --- frame 2 ---
frame2 = tk.Frame(root, bg='#80c1ff') #remove color later
frame2.pack(side="bottom", fill="both", expand=True)
# make a scrollbar
scrollbar = tk.Scrollbar(frame2)
scrollbar.pack(side="right", fill="y")
# make a text box to put the serial output
log = tk.Text (frame2, width=30, height=30, takefocus=0)
log.pack(side="left", fill="both", expand=True)
# attach text box to scrollbar
log.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=log.yview)
# --- frame 2 ---
# after initializing serial, an arduino may need a bit of time to reset
root.after(100, readSerial)
root.mainloop() #here we run our app```
Upvotes: 1