Skip to content

Commit

Permalink
Introduce CustomTkinter UI library and update mockup (#3) (Closes #1)
Browse files Browse the repository at this point in the history
  • Loading branch information
Benedikt-Brunner authored Nov 20, 2024
1 parent 50b63c9 commit a16fe72
Show file tree
Hide file tree
Showing 4 changed files with 559 additions and 61 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ Make sure you have the following installed:
## Development

1. Clone the repository
2. Run `uv sync --extra dev`
2. Create a virtual environment with `uv venv --python=$PythonVersion` where `$PythonVersion` is greater than 3.10.
3. Run `uv sync --extra dev`

To run the project use `uvx tomlscript run`, optionally you can use nodemon for hot reloading with the command `nodemon --exec uvx tomlscript run`.

Expand Down
188 changes: 135 additions & 53 deletions napytau/gui/ui_mockup.py
Original file line number Diff line number Diff line change
@@ -1,60 +1,142 @@
import tkinter as tk
from tkinter import Canvas

import customtkinter
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

from napytau.cli.cli_arguments import CLIArguments
from napytau.core.logic_mockup import logic

customtkinter.set_appearance_mode("System") # Modes: "System" (standard), "Dark", "Light"
customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue"


def plot(value, window) -> Canvas:
# the figure that will contain the plot
fig = Figure(
figsize=(3, 2),
dpi=100,
facecolor="white",
edgecolor="black"
)

# list of squares
y = [(i - 50) ** value for i in range(101)]

# adding the subplot
plot1 = fig.add_subplot(111)

# plotting the graph
plot1.plot(y)

# creating the Tkinter canvas
# containing the Matplotlib figure
canvas = FigureCanvasTkAgg(fig, master=window)
canvas.draw()

return canvas.get_tk_widget()

class App(customtkinter.CTk):
def __init__(self):
super().__init__()

# values

self.tau = tk.IntVar()
self.tau.set(2)

# configure window
self.title("NaPyTau")
self.geometry(f"{1100}x{580}")

# configure grid layout (4x4)
self.grid_columnconfigure(3, weight=1)
self.grid_columnconfigure((1,2), weight=0)
self.grid_rowconfigure((0, 1, 2), weight=1)

# create sidebar frame with widgets
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="NaPyTau",
font=customtkinter.CTkFont(size=20, weight="bold"))
self.logo_label.grid(row=0, column=0, padx=20, pady=(20, 10))
self.sidebar_button_1 = customtkinter.CTkButton(self.sidebar_frame, command=self.sidebar_button_event)
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))
self.scaling_label = customtkinter.CTkLabel(self.sidebar_frame, text="UI Scaling:", anchor="w")
self.scaling_label.grid(row=7, column=0, padx=20, pady=(10, 0))
self.scaling_optionemenu = customtkinter.CTkOptionMenu(self.sidebar_frame,
values=["80%", "90%", "100%", "110%", "120%"],
command=self.change_scaling_event)
self.scaling_optionemenu.grid(row=8, column=0, padx=20, pady=(10, 20))

# create main entry and button
self.entry = customtkinter.CTkEntry(self, textvariable=self.tau)
self.entry.grid(row=3, column=1, columnspan=2, padx=(20, 0), pady=(20, 20), sticky="nsew")

self.main_button_1 = customtkinter.CTkButton(master=self, fg_color="transparent", border_width=2,
text="calc",
text_color=("gray10", "#DCE4EE"), command=self.calc)
self.main_button_1.grid(row=3, column=3, padx=(20, 20), pady=(20, 20), sticky="nsew")

# create line graph

self.line_graph = plot(self.tau.get(), self)
self.line_graph.grid(row=2, column=3, columnspan=1, rowspan=1, padx=(0, 20), pady=(20, 0), sticky="nsew")

# create slider and progressbar frame
self.slider_progressbar_frame = customtkinter.CTkFrame(self, fg_color="transparent")
self.slider_progressbar_frame.grid(row=2, column=2, padx=(20, 0), pady=(20, 0), sticky="nsew")
self.slider_progressbar_frame.grid_columnconfigure(0, weight=1)
self.slider_progressbar_frame.grid_rowconfigure(4, weight=1)
self.slider_2 = customtkinter.CTkSlider(
self.slider_progressbar_frame,
variable=self.tau,
from_=2,
to=5,
number_of_steps=3,
orientation="vertical")
self.slider_2.grid(row=0, column=1, rowspan=5, padx=(10, 10), pady=(10, 10), sticky="ns")

# create textbox
self.label = customtkinter.CTkLabel(self, width=200)
self.label.grid(row=2, column=1, columnspan=1, padx=(20, 0), pady=(20, 0), sticky="nsew")

# set default values
self.appearance_mode_optionemenu.set("Dark")
self.scaling_optionemenu.set("100%")
self.slider_2.configure(command=self.use_slider_value)
self.label.configure(text= "Result: ")

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):
print("sidebar_button click")

def use_slider_value(self, _value):
self.calc()



def calc(self):
entry_value = self.tau.get()

self.label.configure(text=f"Result: {logic(entry_value)}")
self.line_graph = plot(int(entry_value), self)
self.line_graph.grid(row=2, column=3, columnspan=1, rowspan=1, padx=(0, 20), pady=(20, 0), sticky="nsew")


def init(cli_arguments: CLIArguments):
# Create the main window
root = tk.Tk()
root.geometry("800x500") # Set window size
root.title("TPSE Mockup") # Set window title

# Create a StringVar to associate with the button
button_text = tk.StringVar()
label_text = tk.StringVar()
entry_text = tk.StringVar()

def calculate():
string_value = entry_text.get()

if not string_value:
return

num = int(entry_text.get())
result = logic(num)
label_text.set(f"Result: {result}")

# Create the button widget with all options
button_text.set("Calculate!")
button = tk.Button(root,
textvariable=button_text,
anchor=tk.CENTER,
compound=tk.CENTER,
bg="gray",
activebackground="lightgray",
height=3,
width=30,
bd=3,
font=("Arial", 16, "bold"),
cursor="hand2",
fg="black",
padx=15,
pady=15,
justify=tk.CENTER,
wraplength=250,
command=calculate,
)

# Create the label and entry widgets
label_text.set("Result:")
label = tk.Label(root, textvariable=label_text, font=("Arial", 16, "bold"))
entry = tk.Entry(root, textvariable=entry_text, width=50, font=("Arial", 16, "bold"))

# Pack the button into the window
label.pack(pady=30)
entry.pack()
button.pack(pady=20) # Add some padding to the top

# Run the main event loop
root.mainloop()
app = App()
app.mainloop()
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ description = "A modern reimplementation of napatau"
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
"tk>=0.1.0",
"customtkinter>=5.2.2",
"matplotlib>=3.9.2",
]

[build-system]
Expand Down
Loading

0 comments on commit a16fe72

Please sign in to comment.