Related
Every time I click on the buttons I get a error. Could anyone help me by providing a fix or telling me what the issue was because I cant see the issue.
Whenever the button is clicked it is supposed to open a new page and the side bar on the left with the buttons in should stay where they are at.
import tkinter
import tkinter.messagebox
import customtkinter
customtkinter.set_appearance_mode("dark")
customtkinter.set_default_color_theme("dark-blue")
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
# configure window
self.title("Opium")
self.geometry(f"{1100}x{580}")
# configure grid layout (4x4)
self.grid_columnconfigure(1, weight=1)
self.grid_columnconfigure((2, 3), weight=0)
self.grid_rowconfigure((0, 1, 2), weight=1)
# create sidebar frame with widgets
self.content_label = customtkinter.CTkLabel(self, text="", font=customtkinter.CTkFont(size=30, weight="bold"))
self.content_label.grid(row=0, column=1, rowspan=4, sticky="nsew", padx=(10, 0), pady=(20, 10))
self.sidebar_frame = customtkinter.CTkFrame(self, width=140, corner_radius=0)
self.sidebar_frame.grid(row=0, column=0, rowspan=4, sticky="nsew")
self.sidebar_frame.grid_rowconfigure(4, weight=1)
self.logo_label = customtkinter.CTkLabel(self.sidebar_frame, text="Opium", font=customtkinter.CTkFont(size=30, weight="bold"))
self.logo_label.grid(row=0, column=0, padx=20, pady=(20, 10))
self.sidebar_button_1 = customtkinter.CTkButton(self.sidebar_frame, text="Button 1", command=self.sidebar_button_event)
self.sidebar_button_1.grid(row=1, column=0, padx=20, pady=10)
self.sidebar_button_2 = customtkinter.CTkButton(self.sidebar_frame, text="Button 2", command=self.sidebar_button_event)
self.sidebar_button_2.grid(row=2, column=0, padx=20, pady=10)
self.sidebar_button_3 = customtkinter.CTkButton(self.sidebar_frame, text="Button 3", command=self.sidebar_button_event)
self.sidebar_button_3.grid(row=3, column=0, padx=20, pady=10)
self.appearance_mode_label = customtkinter.CTkLabel(self.sidebar_frame, text="Appearance Mode:", anchor="w")
self.appearance_mode_label.grid(row=5, column=0, padx=20, pady=(10, 0))
self.appearance_mode_optionemenu = customtkinter.CTkOptionMenu(self.sidebar_frame, values=["Light", "Dark", "System"],
command=self.change_appearance_mode_event)
self.appearance_mode_optionemenu.grid(row=6, column=0, padx=20, pady=(10, 10))
def open_input_dialog_event(self):
dialog = customtkinter.CTkInputDialog(text="Type in a number:", title="CTkInputDialog")
print("CTkInputDialog:", dialog.get_input())
def change_appearance_mode_event(self, new_appearance_mode: str):
customtkinter.set_appearance_mode(new_appearance_mode)
def change_scaling_event(self, new_scaling: str):
new_scaling_float = int(new_scaling.replace("%", "")) / 100
customtkinter.set_widget_scaling(new_scaling_float)
def sidebar_button_event(self):
try:
self.right_frame.destroy()
except AttributeError:
pass
self.right_frame = customtkinter.CTkFrame(self, bg="white", width=900, height=580)
self.right_frame.grid(row=0, column=1, rowspan=3, columnspan=2, sticky="nsew")
self.home_label = customtkinter.CTkLabel(self.right_frame, text="Home", font=customtkinter.CTkFont(size=30, weight="bold"), bg="white")
self.home_label.pack(side="top", fill="both", padx=20, pady=20)
if __name__ == "__main__":
app = App()
app.mainloop()
I have tested the code and the error you are getting when clicking the buttons is
ValueError: ['bg'] are not supported arguments. Look at the documentation for supported arguments.
As the error already says, bg is not a supported argument by customtkinter.
https://github.com/TomSchimansky/CustomTkinter/wiki/CTkLabel#arguments
In your specific case you have to change the two instances of bg="white" to bg_color="white".
import tkinter
import tkinter.messagebox
import customtkinter
customtkinter.set_appearance_mode("dark")
customtkinter.set_default_color_theme("dark-blue")
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
# configure window
self.title("Opium")
self.geometry(f"{1100}x{580}")
# configure grid layout (4x4)
self.grid_columnconfigure(1, weight=1)
self.grid_columnconfigure((2, 3), weight=0)
self.grid_rowconfigure((0, 1, 2), weight=1)
# create sidebar frame with widgets
self.content_label = customtkinter.CTkLabel(
self, text="", font=customtkinter.CTkFont(size=30, weight="bold"))
self.content_label.grid(
row=0, column=1, rowspan=4, sticky="nsew", padx=(10, 0), pady=(20, 10))
self.sidebar_frame = customtkinter.CTkFrame(
self, width=140, corner_radius=0)
self.sidebar_frame.grid(row=0, column=0, rowspan=4, sticky="nsew")
self.sidebar_frame.grid_rowconfigure(4, weight=1)
self.logo_label = customtkinter.CTkLabel(
self.sidebar_frame, text="Opium", font=customtkinter.CTkFont(size=30, weight="bold"))
self.logo_label.grid(row=0, column=0, padx=20, pady=(20, 10))
self.sidebar_button_1 = customtkinter.CTkButton(
self.sidebar_frame, text="Button 1", command=self.sidebar_button_event)
self.sidebar_button_1.grid(row=1, column=0, padx=20, pady=10)
self.sidebar_button_2 = customtkinter.CTkButton(
self.sidebar_frame, text="Button 2", command=self.sidebar_button_event)
self.sidebar_button_2.grid(row=2, column=0, padx=20, pady=10)
self.sidebar_button_3 = customtkinter.CTkButton(
self.sidebar_frame, text="Button 3", command=self.sidebar_button_event)
self.sidebar_button_3.grid(row=3, column=0, padx=20, pady=10)
self.appearance_mode_label = customtkinter.CTkLabel(
self.sidebar_frame, text="Appearance Mode:", anchor="w")
self.appearance_mode_label.grid(row=5, column=0, padx=20, pady=(10, 0))
self.appearance_mode_optionemenu = customtkinter.CTkOptionMenu(self.sidebar_frame, values=["Light", "Dark", "System"],
command=self.change_appearance_mode_event)
self.appearance_mode_optionemenu.grid(
row=6, column=0, padx=20, pady=(10, 10))
def open_input_dialog_event(self):
dialog = customtkinter.CTkInputDialog(
text="Type in a number:", title="CTkInputDialog")
print("CTkInputDialog:", dialog.get_input())
def change_appearance_mode_event(self, new_appearance_mode: str):
customtkinter.set_appearance_mode(new_appearance_mode)
def change_scaling_event(self, new_scaling: str):
new_scaling_float = int(new_scaling.replace("%", "")) / 100
customtkinter.set_widget_scaling(new_scaling_float)
def sidebar_button_event(self):
try:
self.right_frame.destroy()
except AttributeError:
pass
self.right_frame = customtkinter.CTkFrame(
self, bg_color="white", width=900, height=580)
self.right_frame.grid(row=0, column=1, rowspan=3,
columnspan=2, sticky="nsew")
self.home_label = customtkinter.CTkLabel(
self.right_frame, text="Home", font=customtkinter.CTkFont(size=30, weight="bold"), bg_color="white")
self.home_label.pack(side="top", fill="both", padx=20, pady=20)
if __name__ == "__main__":
app = App()
app.mainloop()
For the next time please be so kind and include the error message you are getting with your question
I'm trying to create an app with a frame with two frames inside, but I want one of then to be wider than the other... I found a way to do it using grid, but when I add a scrollbar on one of the frames it readjusts the grid and both frames get the same size.
Here is the code working without the scrollbar:
def __init__(self, master=None):
ctk.set_appearance_mode('system')
ctk.set_default_color_theme('blue')
self.__root = ctk.CTk() if master is None else ctk.CTkToplevel(master)
self.__root. Configure(height=1500, width=944)
self.__root.minsize(1500, 944)
self.__main_container = ctk.CTkFrame(self.__root)
self.__image_frame = ctk.CTkFrame(self.__main_container)
self.__image_frame.configure(height=800, width=1000)
self.__image_canvas = ctk.CTkCanvas(self.__image_frame)
self.__image_canvas.configure(confine="true", cursor="crosshair")
self.__image_canvas.grid(column=0, row=0, sticky="nsew")
self.__image_canvas.bind("<ButtonPress-1>", self.__start_drawing)
self.__image_canvas.bind("<ButtonRelease-1>", self.__end_drawing)
self.__image_canvas.bind("<B1-Motion>", self.__draw_rectangle)
self.__image_frame.grid(column=0, padx=10, pady=20, row=0, sticky="nsew")
self.__image_frame.grid_propagate(0)
self.__image_frame.grid_anchor("center")
self.__image_frame.rowconfigure(0, weight=1)
self.__image_frame.columnconfigure(0, weight=1)
self.__boxes_frame = ctk.CTkFrame(self.__main_container)
self.__boxes_frame.configure(height=800, width=400)
self.__boxes_frame.grid(column=1, padx=10, pady=20, row=0, sticky="ns")
self.__main_container.grid(column=0, padx=20, pady=40, row=0, sticky="ns")
self.__main_container.grid_anchor("center")
self.__main_container.rowconfigure(0, weight=1)
self.__root.grid_anchor("center")
self.__root.rowconfigure(0, weight=1)
self.mainwindow = self.__root
And this is the code when I add the scrollbar and messes the grid
def __init__(self, master=None):
ctk.set_appearance_mode('system')
ctk.set_default_color_theme('blue')
self.__root = ctk.CTk() if master is None else ctk.CTkToplevel(master)
self.__root. Configure(height=1500, width=944)
self.__root.minsize(1500, 944)
self.__main_container = ctk.CTkFrame(self.__root)
self.__image_frame = ctk.CTkFrame(self.__main_container)
self.__image_frame.configure(height=800, width=1000)
self.__image_canvas = ctk.CTkCanvas(self.__image_frame)
self.__image_canvas.configure(confine="true", cursor="crosshair")
self.__image_canvas.grid(column=0, row=0, sticky="nsew")
self.__image_canvas.bind("<ButtonPress-1>", self.__start_drawing)
self.__image_canvas.bind("<ButtonRelease-1>", self.__end_drawing)
self.__image_canvas.bind("<B1-Motion>", self.__draw_rectangle)
#------ adding the scrollbar -----
self.__image_frame_vertical_scrollbar = ctk.CTkScrollbar(self.__image_frame, orientation="vertical")
self.__image_frame_vertical_scrollbar.grid(column=1, row=0, sticky="ns")
self.__image_frame_vertical_scrollbar.configure(command=self.__image_canvas.yview)
self.__image_canvas.configure(yscrollcommand=self.__image_frame_vertical_scrollbar.set)
#---------------------------------
self.__image_frame.grid(column=0, padx=10, pady=20, row=0, sticky="nsew")
self.__image_frame.grid_propagate(0)
self.__image_frame.grid_anchor("center")
self.__image_frame.rowconfigure(0, weight=1)
self.__image_frame.columnconfigure(0, weight=1)
self.__boxes_frame = ctk.CTkFrame(self.__main_container)
self.__boxes_frame.configure(height=800, width=400)
self.__boxes_frame.grid(column=1, padx=10, pady=20, row=0, sticky="ns")
self.__main_container.grid(column=0, padx=20, pady=40, row=0, sticky="ns")
self.__main_container.grid_anchor("center")
self.__main_container.rowconfigure(0, weight=1)
self.__root.grid_anchor("center")
self.__root.rowconfigure(0, weight=1)
self.mainwindow = self.__root
What is wrong with the grid definition that is messing things up? How can I set the __image_frame grid to it fills the __main_container keeping the desired dimensions?
Set the size of the canvas explicitly
self.__image_canvas = ctk.CTkCanvas(self.__image_frame, width=900)
Yes there are many stackoverflow questions regarding this, i saw everything but could not get this working so i am asking a new question with my code:
Basically i want to create a table in tkinter with 4 columns. But i want to be able to scroll this because the rows will be later taken from the mysql database. but i cannot get the scroll working.
Here is my code :
from tkinter import *
root = Tk()
root.geometry("700x600")
frame_canvas = Frame(root)
frame_canvas.rowconfigure(0, weight=1)
frame_canvas.columnconfigure(0, weight=1)
frame_canvas.grid(row=0, column=0, sticky="news")
canvas = Canvas(frame_canvas)
canvas.grid(row=0, column=0, sticky="news")
vsb = Scrollbar(frame_canvas, orient="vertical", command=canvas.yview)
vsb.grid(row=0, column=1, sticky='ns')
canvas.configure(yscrollcommand=vsb.set)
for i in range(0, 50):
for j in range(0, 4):
canvas.columnconfigure(j, minsize=150)
Label(canvas, text="hello"+str(i)+str(j)).grid(row=i, column=j)
canvas.config(scrollregion=canvas.bbox("all"))
app = root
root.mainloop()
How to i get the canvas to scroll ? Is there another way to create a table ? Also later if i want to add a row to the bottom of the table, how is it possible ? or do i have to clear the whole canvas and re-render it or something ?
EDIT
Have added a frame window to the canvas. Still scroll won't work. That could be the issue now ?
from tkinter import *
root = Tk()
root.geometry("700x600")
frame_canvas = Frame(root)
frame_canvas.rowconfigure(0, weight=1)
frame_canvas.columnconfigure(0, weight=1)
frame_canvas.grid(row=0, column=0, sticky="news")
canvas = Canvas(frame_canvas, height=600, width=500)
canvas.grid(row=0, column=0, sticky="news")
vsb = Scrollbar(frame_canvas, command=canvas.yview, orient="vertical")
vsb.grid(row=0, column=1, sticky='ns')
canvas.configure(yscrollcommand=vsb.set)
frame2 = Frame(canvas, bg="powder blue", height=600, width=700)
canvas.create_window((0, 0), anchor="nw", height=600, width=600, window=frame2)
for i in range(0, 50):
for j in range(0, 4):
frame2.columnconfigure(j, minsize=120)
Label(frame2, bg="powder blue", text="hello"+str(i)+str(j)).grid(row=i, column=j)
canvas.config(scrollregion=frame2.bbox("all"))
app = root
root.mainloop()
Thanks for taking time to look at this. I've been struggling with this for almost a week and its driving me crazy.
I have a horizontal Paned Window which is supposed to stretch from the bottom of my toolbar to the bottom of my window, but it's sticking only to the bottom of the root window. Eventually I want to have a Treeview widget in the left pane and thumbnails in the right pane.
Can anyone help me to get the Paned Window to stick NSEW? Do I need to put it inside another frame?
I'm using Python 2.7 on Windows 7. (This isn't my whole program, just a sample to demonstrate the problem.)
#!/usr/bin/env python
# coding=utf-8
from Tkinter import *
from ttk import *
class MainWindow:
def null(self):
pass
def __init__(self):
self.root = Tk()
self.root.geometry("700x300")
self.root.resizable(width=TRUE, height=TRUE)
self.root.rowconfigure(0, weight=1)
self.root.columnconfigure(0, weight=1)
self.menubar = Menu(self.root)
File_menu = Menu(self.menubar, tearoff=0)
self.menubar.add_cascade(label="Pandoras Box", menu=File_menu)
File_menu.add_command(label="Black Hole", command=self.null)
self.root.config(menu=self.menubar)
self.toolbar = Frame(self.root, relief=RAISED)
self.toolbar.grid(row=0, column=0, sticky='NEW')
self.toolbar.grid_columnconfigure(0, weight=1)
self.toolbar.rowconfigure(0, weight=1)
dummy = Button(self.toolbar, text="Tool Button")
dummy.grid(row=0, column=0, sticky='EW')
Find = Label(self.toolbar, text="Search")
Search = Entry(self.toolbar)
Find.grid(row=0, column=5, sticky='E', padx=6)
Search.grid(row=0, column=6, sticky='E', padx=8)
self.info_column = Frame(self.root, relief=RAISED, width=100)
self.info_column.grid(row=0, column=5, rowspan=3, sticky='NSW')
self.info_column.grid_rowconfigure(0, weight=1)
self.info_column.grid_columnconfigure(0, weight=1)
self.rootpane = PanedWindow(self.root, orient=HORIZONTAL)
self.rootpane.grid(row=1, column=0, sticky='NS')
self.rootpane.grid_rowconfigure(0, weight=1)
self.rootpane.grid_columnconfigure(0, weight=1)
self.leftpane = Frame(self.rootpane, relief=RAISED)
self.leftpane.grid(row=0, column=0, sticky='NSEW')
self.rightpane = Frame(self.rootpane, relief=RAISED)
self.rightpane.grid(row=0, column=0, sticky='NSEW')
''' THESE BUTTONS ARE SUPPOSED TO BE INSIDE PANED WINDOW STUCK TO THE TOP!'''
but_left = Button(self.leftpane, text="SHOULD BE IN LEFT PANE UNDER TOOLBAR FRAME")
but_left.grid(row=0, column=0, sticky='NEW')
but_right = Button(self.rightpane, text="SHOULD BE IN RIGHT PANE UNDER TOOLBAR FRAME")
but_right.grid(row=0, column=0, sticky='NEW')
self.rootpane.add(self.leftpane)
self.rootpane.add(self.rightpane)
self.SbarMesg = StringVar()
self.label = Label(self.root, textvariable=self.SbarMesg, font=('arial', 8, 'normal'))
self.SbarMesg.set('Status Bar:')
self.label.grid(row=3, column=0, columnspan=6, sticky='SEW')
self.label.grid_rowconfigure(0, weight=1)
self.label.grid_columnconfigure(0, weight=1)
self.root.mainloop()
a = MainWindow()
Short answer: the space you see between the buttons and the toolbar frame is because you allow the row containing the toolbar to resize, instead of the row containing the PanedWindow... To get what you want, replace:
self.root.rowconfigure(0, weight=1)
with
self.root.rowconfigure(1, weight=1)
Other comments:
Try to avoid wildcard imports. In this case, it makes it difficult to differentiate between tk and ttk widgets
To allow resizing of widgets aligned using grid(), .rowconfigure(..., weight=x) must be called on the widget's parent not the widget itself.
background colors are very useful to debug alignment issues in tkinter.
Code:
import Tkinter as tk
import ttk
class MainWindow:
def __init__(self):
self.root = tk.Tk()
self.root.geometry("700x300")
self.root.resizable(width=tk.TRUE, height=tk.TRUE)
self.root.rowconfigure(1, weight=1)
self.root.columnconfigure(0, weight=1)
self.toolbar = tk.Frame(self.root, relief=tk.RAISED, bg="yellow")
self.toolbar.grid(row=0, column=0, sticky='NEW')
self.toolbar.columnconfigure(0, weight=1)
dummy = ttk.Button(self.toolbar, text="Tool Button")
dummy.grid(row=0, column=0, sticky='EW')
Find = tk.Label(self.toolbar, text="Search")
Search = ttk.Entry(self.toolbar)
Find.grid(row=0, column=5, sticky='E', padx=6)
Search.grid(row=0, column=6, sticky='E', padx=8)
self.info_column = tk.Frame(self.root, relief=tk.RAISED, width=100, bg="orange")
self.info_column.grid(row=0, column=5, rowspan=2, sticky='NSW')
self.rootpane = tk.PanedWindow(self.root, orient=tk.HORIZONTAL, bg="blue")
self.rootpane.grid(row=1, column=0, sticky='NSEW')
self.leftpane = tk.Frame(self.rootpane, bg="pink")
self.rootpane.add(self.leftpane)
self.rightpane = tk.Frame(self.rootpane, bg="red")
self.rootpane.add(self.rightpane)
''' THESE BUTTONS ARE SUPPOSED TO BE INSIDE PANED WINDOW STUCK TO THE TOP!'''
but_left = ttk.Button(self.leftpane, text="SHOULD BE IN LEFT PANE UNDER TOOLBAR FRAME")
but_left.grid(row=0, column=0, sticky='NEW')
but_right = ttk.Button(self.rightpane, text="SHOULD BE IN RIGHT PANE UNDER TOOLBAR FRAME")
but_right.grid(row=0, column=0, sticky='NEW')
self.label = tk.Label(self.root, text="Status:", anchor="w")
self.label.grid(row=3, column=0, columnspan=6, sticky='SEW')
self.root.mainloop()
a = MainWindow()
I tried to find out why, but maybe don't know the right questions. I have a project where I'm trying to create a dashboard for my car. The problem is that when I try to make a canvas object from another class appear my GUI starts but does not show anything. If I start the GUI without asking for the canvas to appear the GUI works and shows the screen. I'm new to Python. My version is 3.5
My Main program:
from tkinter import*
from helperThingys import Helpers
root = Tk()
root.geometry("800x480")
bgLeft = Frame(root, bg="black", width=200, height=480)
bgLeft.pack_configure(fill=BOTH, expand=1, side=LEFT)
bgMiddle = Frame(root, bg="black", width=400, height=480)
bgMiddle.pack_configure(fill=BOTH, expand=1, side=LEFT)
bgRight = Frame(root, bg="black", width=200, height=480)
bgRight.pack_configure(fill=BOTH, expand=1, side=LEFT)
# These are really gif images read to labels to be able to grid them
# now just plain text labels for convenience.
label_4hi = Label(bgLeft, text="ok", bg="green")
label_4lo = Label(bgLeft, text="ok", bg="green")
label_lock = Label(bgLeft, text="ok", bg="green")
label_batt = Label(bgMiddle, text="ok", bg="red")
label_fuelF = Label(bgLeft, text="ok", bg="orange")
label_glow = Label(bgLeft, text="ok", bg="yellow")
label_hb = Label(bgMiddle, text="ok", bg="blue")
label_indL = Label(bgMiddle, text="ok", bg="green")
label_indR = Label(bgMiddle, text="ok", bg="green")
label_lowFuel = Label(bgLeft, text="ok", bg="red")
label_lowOil = Label(bgLeft, text="ok", bg="red")
label_park = Label(bgMiddle, text="ok", bg="red")
label_pwrS = Label(bgLeft, text="ok", bg="red")
label_rFog = Label(bgLeft, text="ok", bg="orange")
label_temp = Label(bgLeft, text="ok", bg="red")
label_gauge = Label(bgMiddle, text="ok", bg="red")
# Middle frame
bgMiddle.rowconfigure(0, minsize=46, weight=1)
bgMiddle.rowconfigure(1, minsize=217, weight=5)
bgMiddle.rowconfigure(2, minsize=217, weight=5)
bgMiddle.columnconfigure(0, minsize=80)
bgMiddle.columnconfigure(1, minsize=80)
bgMiddle.columnconfigure(2, minsize=80)
bgMiddle.columnconfigure(3, minsize=80)
bgMiddle.columnconfigure(4, minsize=80)
label_indL.grid(row=0, column=0, sticky=E+N+W)
label_hb.grid(row=0, column=1, sticky=E+N+S+W)
label_park.grid(row=0, column=2, sticky=E+N+S+W)
label_batt.grid(row=0, column=3, sticky=E+N+S+W)
label_indR.grid(row=0, column=4, sticky=E+N+S+W)
# Left frame
bgLeft.rowconfigure(0, minsize=46, weight=1)
bgLeft.rowconfigure(1, minsize=46, weight=1)
bgLeft.rowconfigure(2, minsize=46, weight=1)
bgLeft.rowconfigure(3, minsize=46, weight=1)
bgLeft.rowconfigure(4, minsize=46, weight=1)
bgLeft.columnconfigure(0, minsize=100)
bgLeft.columnconfigure(1, minsize=100)
label_4hi.grid(row=0, column=0, sticky=E+N+S+W)
label_4lo.grid(row=0, column=1, sticky=E+N+S+W)
label_lock.grid(row=1, column=0, sticky=E+N+S+W)
label_pwrS.grid(row=1, column=1, sticky=E+N+S+W)
label_rFog.grid(row=2, column=0, sticky=E+N+S+W)
label_lowFuel.grid(row=2, column=1, sticky=E+N+S+W)
label_lowOil.grid(row=3, column=0, sticky=E+N+S+W)
label_temp.grid(row=3, column=1, sticky=E+N+S+W)
label_fuelF.grid(row=4, column=0, sticky=E+N+S+W)
label_glow.grid(row=4, column=1, sticky=E+N+S+W)
# Middle frame
speedo = helpers.Gauge()
speedo.makeGauge(bgMiddle, 150, "speed")
speedo.grid(row=1, columnspan=5, sticky=E+N+S+W)
#label_gauge.grid(row=1, columnspan=5, sticky=E+N+S+W)
# Right Frame
#oilPres = Gauge(bgRight, 150, "oilPres")
root.mainloop()
And here is the 'helpers.py' from helperThingys package.
from tkinter import Canvas
class Gauge(Canvas):
def __init__(self):
Canvas.__init__(self)
pass
def makeGauge(self, window, value, gaugeType):
if gaugeType == "speed":
baseCanvas = Canvas(window, bg="black", width=400, height=217,
highlightthickness=0)
baseCanvas.create_arc([10, 5, 390, 395], start=0, extent=180,
fill="white")
return baseCanvas
I'm using the canvases as the background for the gauges. The strange thing was that this 'helpers.py' worked and created the canvases to my GUI when it was not a class but a module:
def makeGauge(self, window, value, gaugeType):
if gaugeType == "speed":
baseCanvas = Canvas(window, bg="black", width=400, height=217,
highlightthickness=0)
baseCanvas.create_arc([10, 5, 390, 395], start=0, extent=180,
fill="white")
return baseCanvas
... and so on (the module was then in the same package as the GUI). That's why I know that the canvases work with the GUI. What am I doing wrong when using them in a class?
Thank you for your answers.
Your problem is that Gauge both is a subclass of Canvas and creates one or more other canvases (that are, oddly, a child of some other window).
When you call makeGauge, this creates the second canvas, and returns it. However, you don't save a reference and you never call pack, place or grid on this second canvas so it never shows up.
I don't know what you're intending to do with the two canvases, but I'm guessing you really only want one. I suggest making the class like this, where you pass all arguments in at the time you create the canvas, so that you can create the gauge in a single step:
class Gauge(Canvas):
def __init__(self, parent, value, gaugeType):
Canvas.__init__(self, parent)
self.makeGauge(value, gaugeType)
def makeGauge(self, value, gaugeType):
if gaugeType == "speed":
self.configure(bg="black", width=400, height=217,
highlightthickness=0)
self.create_arc([10, 5, 390, 395], start=0, extent=180,
fill="white")
elif gaugeType == "rpm":
...
speedo = Gauge(bgMiddle, 150, "speed")
speedo.grid(...)
If you want to keep both canvases, or you decide to make Gauge inherit from something else, you need to save the reference that is returned by makeGauge, and then add it to the display:
gauge = speedo.makeGauge(bgMiddle, 150, "speed")
gauge.grid(row=1, columnspan=5, sticky=E+N+S+W)