121 lines
4.6 KiB
Python
121 lines
4.6 KiB
Python
import tkinter as tk
|
|
from tkinter import ttk
|
|
import threading
|
|
|
|
from .serial_reader import WeightReader
|
|
from .config import DEFAULT_CALIB, DISPLAY_TYPES
|
|
|
|
class WeightApp(tk.Tk):
|
|
def __init__(self, weight_reader):
|
|
super().__init__()
|
|
self.weight_reader: WeightReader = weight_reader
|
|
|
|
self.toolbar = tk.Frame(self, padx=10)
|
|
self.toolbar.pack(side=tk.LEFT)
|
|
|
|
#### Connection Settings ####
|
|
self.connection_settings = tk.Frame(self.toolbar, pady=10)
|
|
self.scan_ports_button = ttk.Button(self.connection_settings, text="Scan Devices", command=self.update_devices)
|
|
self.scan_ports_button.pack()
|
|
self.port_label = ttk.Label(self.connection_settings, text="Port:")
|
|
self.port_label.pack(side=tk.LEFT)
|
|
self.port = ttk.Combobox(self.connection_settings, values=[])
|
|
self.update_devices()
|
|
self.port.pack(side=tk.LEFT)
|
|
self.connection_settings.pack()
|
|
self.connect_button = ttk.Button(self.toolbar, text="Connect", command=self.connect)
|
|
self.connect_button.pack()
|
|
|
|
#### Weight Reader Settings ####
|
|
self.reader_settings = tk.Frame(self.toolbar, pady=30)
|
|
self.reader_settings.pack()
|
|
|
|
self.calib_factor = tk.Frame(self.reader_settings)
|
|
self.calib_factor.pack()
|
|
self.calib_label = ttk.Label(self.calib_factor, text="Calibration Factor:")
|
|
self.calib_label.pack()
|
|
self.calib_weight = ttk.Combobox(self.calib_factor, values=[100], width=5)
|
|
self.calib_weight.set(100)
|
|
self.calib_weight.pack(side=tk.LEFT)
|
|
self.calib_measurements = ttk.Entry(self.calib_factor)
|
|
self.calib_measurements.insert(0, DEFAULT_CALIB)
|
|
self.calib_measurements.pack(side=tk.LEFT)
|
|
self.update_calib_button = ttk.Button(self.reader_settings, text="Update Calibration", command=self.update_calib)
|
|
self.update_calib_button.pack()
|
|
|
|
self.display_type = tk.Frame(self.toolbar, pady=20)
|
|
self.display_type.pack()
|
|
self.display_type_label = ttk.Label(self.display_type, text="Visual:")
|
|
self.display_type_label.pack(side=tk.LEFT)
|
|
self.display_type_select = ttk.Combobox(self.display_type, values=[t.value for t in DISPLAY_TYPES])
|
|
self.display_type_select.set(DISPLAY_TYPES.NUMBER.value)
|
|
self.display_type_select.pack(side=tk.LEFT)
|
|
|
|
|
|
#### Display ####
|
|
self.main_frame = tk.Frame(self, width=144, height=168, padx=50)
|
|
self.main_frame.pack(side=tk.RIGHT)
|
|
|
|
#### Actions ####
|
|
self.actions = tk.Frame(self.main_frame)
|
|
self.actions.pack()
|
|
self.tare_button = ttk.Button(self.actions, text="Tare", command=self.weight_reader.tare)
|
|
self.tare_button.pack()
|
|
|
|
self.canvas = tk.Canvas(self.main_frame, width=144, height=168, background='white')
|
|
self.canvas.pack()
|
|
|
|
self.label = self.canvas.create_text(50, 68, text="0.0 g", font=("Arial", 18), fill='black', justify='left')
|
|
|
|
self.update_weight_display()
|
|
|
|
self.focus_force()
|
|
|
|
|
|
def connect(self):
|
|
if self.weight_reader.serial is None:
|
|
port = self.port.get()
|
|
self.weight_reader.connect(port)
|
|
self.connect_button.config(text="Disconnect")
|
|
self.connection_settings.pack_forget()
|
|
else:
|
|
self.weight_reader.disconnect()
|
|
self.connect_button.config(text="Connect")
|
|
self.connect_button.pack_forget()
|
|
self.reader_settings.pack_forget()
|
|
self.actions.pack_forget()
|
|
self.connection_settings.pack()
|
|
self.connect_button.pack()
|
|
self.reader_settings.pack()
|
|
self.actions.pack()
|
|
|
|
def update_devices(self):
|
|
self.weight_reader.scan_devices()
|
|
self.port.config(values=self.weight_reader.ports)
|
|
if len(self.weight_reader.ports) > 0:
|
|
self.port.set(self.weight_reader.ports[0])
|
|
|
|
def update_calib(self):
|
|
self.weight_reader.calib_factor = self.calib_weight.get() / float(self.calib_measurements.get())
|
|
|
|
|
|
def update_weight_display(self):
|
|
weight = self.weight_reader.value
|
|
self.canvas.itemconfig(self.label, text=f"{weight:.1f} g")
|
|
self.after(100, self.update_weight_display)
|
|
|
|
def main():
|
|
weight_reader = WeightReader()
|
|
threading.Thread(target=weight_reader.read_weights, daemon=True).start()
|
|
|
|
app = WeightApp(weight_reader)
|
|
app.protocol("WM_DELETE_WINDOW", lambda: on_closing(app, weight_reader))
|
|
app.mainloop()
|
|
|
|
def on_closing(app, weight_reader):
|
|
weight_reader.stop()
|
|
app.destroy()
|
|
|
|
if __name__ == "__main__":
|
|
main()
|