main.py (34632B)
1 import ctypes 2 3 def enable_high_dpi_awareness(): 4 try: 5 # Windows 8.1+ 6 ctypes.windll.shcore.SetProcessDpiAwareness(2) # PROCESS_PER_MONITOR_DPI_AWARE 7 except Exception: 8 try: 9 # Windows Vista–8.0 10 ctypes.windll.user32.SetProcessDPIAware() 11 except Exception: 12 pass 13 14 enable_high_dpi_awareness() 15 16 17 import math 18 from preamble import ThreadCalculator, ThreadDatabase, InputParser 19 import tkinter as tk 20 from tkinter import ttk 21 import os 22 import sys 23 24 def resource_path(relative_path): 25 """ Get absolute path to resource, works for dev and for PyInstaller """ 26 try: 27 base_path = sys._MEIPASS 28 except Exception: 29 base_path = os.path.abspath(".") 30 return os.path.join(base_path, relative_path) 31 32 33 34 class App(tk.Tk): 35 def __init__(self): 36 super().__init__() 37 38 39 # Adjust scaling for high-DPI displays 40 41 dpi = self.winfo_fpixels('1i') 42 scale_factor = dpi / 72.0 43 44 # Apply scaling to Tkinter 45 self.tk.call('tk', 'scaling', scale_factor) 46 47 # Optional: also set a nicer default font 48 self.option_add("*Font", ("Segoe UI", 10)) 49 50 51 self.bind_enter_to_button() 52 53 54 55 icon = tk.PhotoImage(file=resource_path("icon.png")) 56 self.iconphoto(True, icon) 57 58 self.title("Thread Calculator") 59 self.minsize(950, 400) 60 61 62 self.parser = InputParser() 63 self.db_td = ThreadDatabase(resource_path("T_d.csv")) 64 self.db_es = ThreadDatabase(resource_path("es.csv")) 65 66 self.columnconfigure(0, weight=2) 67 self.columnconfigure(1, weight=1) 68 self.rowconfigure(0, weight=7) 69 self.rowconfigure(1, weight=3) 70 71 self.container = ttk.Frame(self) 72 self.container.pack(expand=True, fill="both") 73 74 self.main_menu = self.build_main_menu() 75 self.ext_env = self.build_ext_env() 76 self.int_env = self.build_int_env() 77 78 self.show(self.main_menu) 79 80 def bind_enter_to_button(self): 81 def trigger_focused_button(event): 82 widget = self.focus_get() 83 if isinstance(widget, tk.Button) or isinstance(widget, ttk.Button): 84 widget.invoke() # Trigger the button's command 85 self.bind_all("<Return>", trigger_focused_button) 86 87 def show(self, frame): 88 frame.tkraise() 89 90 91 92 # ----------------- MAIN MENU ------------------ 93 def build_main_menu(self): 94 frame = ttk.Frame(self.container) 95 frame.place(relwidth=1, relheight=1) 96 97 frame_buttons = ttk.Frame(frame) 98 frame_buttons.pack(pady=50) 99 100 # Buttons 101 btn_ext = ttk.Button(frame_buttons, text="External Thread Calculator", 102 command=lambda: self.show(self.ext_env)) 103 btn_ext.pack(padx=10, pady=20) 104 105 btn_int = ttk.Button(frame_buttons, text="Internal Thread Calculator", 106 command=lambda: self.show(self.int_env)) 107 btn_int.pack(padx=10) 108 109 return frame 110 111 # ---------------- EXTERNAL THREAD ENVIRONMENT ------------------ 112 def build_ext_env(self): 113 frame = ttk.Frame(self.container) 114 frame.place(relwidth=1, relheight=1) 115 116 ttk.Button(frame, text="← Back", command=lambda: self.show(self.main_menu)).pack(anchor="w", pady=5, padx=5) 117 118 notebook = ttk.Notebook(frame) 119 notebook.pack(expand=True, fill="both", padx=5, pady=5) 120 121 # --- TAB 1: EXTERNAL THREAD WITH RUNOUT --- # 122 tab_runout = ttk.Frame(notebook) 123 tab_runout.columnconfigure(0, weight=1, uniform="half") 124 tab_runout.columnconfigure(1, weight=1, uniform="half") 125 tab_runout.rowconfigure(0, weight=1) 126 127 notebook.add(tab_runout, text="With Runout") 128 129 tab_runout_left = ttk.LabelFrame(tab_runout, text="Input") 130 tab_runout_left.grid(row=0, column=0, padx=5, pady=5, sticky="nsew") 131 tab_runout_left.columnconfigure(0, weight=1) 132 tab_runout_left.rowconfigure(1, weight=1) 133 tab_runout_left.rowconfigure(0, weight=3) 134 135 136 tab_runout_left_top = ttk.Frame(tab_runout_left) 137 tab_runout_left_top.grid(row=0, column=0, padx=5, pady=5, sticky="new") 138 tab_runout_left_top.columnconfigure(1, weight=1, uniform="half") 139 tab_runout_left_top.columnconfigure(0, weight=1, uniform="half") 140 141 142 143 tab_runout_left_bottom = ttk.Frame(tab_runout_left) 144 tab_runout_left_bottom.grid(row=1, column=0, padx=5, pady=5, sticky="sew") 145 tab_runout_left_bottom.columnconfigure(0, weight=1) 146 tab_runout_left_bottom.columnconfigure(1, weight=1) 147 148 149 150 tab_runout_right = ttk.LabelFrame(tab_runout, text="Output") 151 tab_runout_right.grid(row=0, column=1, padx=5, pady=5, sticky="nsew") 152 tab_runout_right.columnconfigure(0, weight=1) 153 tab_runout_right.rowconfigure(0, weight=1) 154 155 tk.Label(tab_runout_left_top, text="Designation:").grid(padx=5, pady=5, row=0, column=0, sticky="nse") 156 runout_designation_entry = ttk.Entry(tab_runout_left_top) 157 runout_designation_entry.grid(padx=5, pady=5, row=0, column=1, sticky="nsew") 158 159 tk.Label(tab_runout_left_top, text="Thread start point and its length:").grid(padx=5, pady=5, row=1, column=0, sticky="nse") 160 runout_sl_entry = ttk.Entry(tab_runout_left_top) 161 runout_sl_entry.grid(padx=5, pady=5, row=1, column=1, sticky="nsew") 162 163 # CALCULATIONS FOR EXTERNAL THREAD WITH RUNOUT 164 165 def calc_runout(): 166 runout_output_box.config(state="normal") 167 runout_output_box.delete("1.0", tk.END) 168 169 designation = runout_designation_entry.get() 170 designation_parsed = self.parser.parse_designation(designation) 171 if isinstance(designation_parsed, str): 172 runout_output_box.insert(tk.END, designation_parsed + "\n") 173 runout_output_box.config(state="disabled") 174 return 175 d, pitch, grade, class_letter = designation_parsed 176 177 sl = runout_sl_entry.get() 178 sl_parsed = self.parser.parse_sl(sl) 179 if isinstance(sl_parsed, str): 180 runout_output_box.insert(tk.END, sl_parsed + "\n") 181 runout_output_box.config(state="disabled") 182 return 183 s, l = sl_parsed 184 185 T_d_value = self.db_td.lookup_value_T_d(diameter=d, pitch=pitch, grade=grade) 186 if T_d_value is None: 187 runout_output_box.insert(tk.END, "No T_d-value found in database!\n") 188 runout_output_box.config(state="disabled") 189 return 190 191 es_value = self.db_es.lookup_value_es(pitch=pitch, class_letter=class_letter) 192 if es_value is None: 193 runout_output_box.insert(tk.END, "No es-value found in database!\n") 194 runout_output_box.config(state="disabled") 195 return 196 197 198 depth = ThreadCalculator.calc_depth(pitch, es_value, T_d_value) 199 fal = ThreadCalculator.cal_fal(pitch) 200 noc = ThreadCalculator.calc_noc(pitch) 201 202 # DISPLAY RESULTS 203 runout_output_box.insert(tk.END, f"SPL: {s}\n") 204 runout_output_box.insert(tk.END, f"DM1: {d}\n") 205 runout_output_box.insert(tk.END, f"FPL: {s - l - 2.5*pitch}\n") 206 runout_output_box.insert(tk.END, f"APP: {pitch}\n") 207 runout_output_box.insert(tk.END, f"ROP: {2.5*pitch}\n") 208 runout_output_box.insert(tk.END, f"TDEP: {depth:.4f}\n") 209 runout_output_box.insert(tk.END, f"FAL: {fal}\n") 210 runout_output_box.insert(tk.END, f"IANG: 28\n") 211 if noc is None: 212 runout_output_box.insert(tk.END, f"NRC: {noc}, choose different pitch (0.5-6)!\n") 213 else: 214 runout_output_box.insert(tk.END, f"NRC: {noc-1}\n") 215 runout_output_box.insert(tk.END, f"PIT: {pitch}\n") 216 runout_output_box.insert(tk.END, f"VARI: 300103 (constant area!)\n") 217 218 runout_output_box.config(state="disabled") 219 220 def clear_runout_output(): 221 runout_output_box.config(state="normal") 222 runout_output_box.delete("1.0", tk.END) 223 runout_output_box.config(state="disabled") 224 225 ttk.Button(tab_runout_left_bottom, text="Calculate", command=calc_runout).grid(padx=5, pady=5, row=5, column=0, sticky="sew") 226 227 228 229 ttk.Button(tab_runout_left_bottom, text="Clear Output", command=clear_runout_output).grid(padx=5, pady=5, row=5, column=1, sticky="sew") 230 231 232 233 runout_output_box = tk.Text(tab_runout_right) 234 runout_output_box.grid(padx=5, pady=5, row=0, column=0, sticky="nsew") 235 runout_output_box.config(state="disabled") # Read-only initially 236 237 238 239 240 241 242 243 # --- TAB 2: EXTERNAL THREAD WITH UNDERCUT --- # 244 tab_undercut = ttk.Frame(notebook) 245 tab_undercut.columnconfigure(0, weight=1, uniform="half") 246 tab_undercut.columnconfigure(1, weight=1, uniform="half") 247 tab_undercut.rowconfigure(0, weight=1) 248 249 notebook.add(tab_undercut, text="With Undercut") 250 251 tab_undercut_left = ttk.LabelFrame(tab_undercut, text="Input") 252 tab_undercut_left.grid(row=0, column=0, padx=5, pady=5, sticky="nsew") 253 tab_undercut_left.columnconfigure(0, weight=1) 254 tab_undercut_left.rowconfigure(1, weight=1) 255 tab_undercut_left.rowconfigure(0, weight=3) 256 tab_undercut_left.rowconfigure(1, weight=1) 257 258 259 tab_undercut_left_top = ttk.Frame(tab_undercut_left) 260 tab_undercut_left_top.grid(row=0, column=0, padx=5, pady=5, sticky="new") 261 tab_undercut_left_top.columnconfigure(1, weight=1, uniform="half") 262 tab_undercut_left_top.columnconfigure(0, weight=1, uniform="half") 263 264 tab_undercut_left_bottom = ttk.Frame(tab_undercut_left) 265 tab_undercut_left_bottom.grid(row=1, column=0, padx=5, pady=5, sticky="sew") 266 tab_undercut_left_bottom.columnconfigure(0, weight=1) 267 tab_undercut_left_bottom.columnconfigure(1, weight=1) 268 269 tab_undercut_right = ttk.LabelFrame(tab_undercut, text="Output") 270 tab_undercut_right.grid(row=0, column=1, padx=5, pady=5, sticky="nsew") 271 tab_undercut_right.columnconfigure(0, weight=1) 272 tab_undercut_right.rowconfigure(0, weight=1) 273 274 275 276 tk.Label(tab_undercut_left_top, text="Designation:").grid(padx=5, pady=5, row=0, column=0, sticky="nse") 277 undercut_designation_entry = ttk.Entry(tab_undercut_left_top) 278 undercut_designation_entry.grid(padx=5, pady=5, row=0, column=1, sticky="nsew") 279 280 tk.Label(tab_undercut_left_top, text="Thread start point and its length:").grid(padx=5, pady=5, row=1, column=0, sticky="nse") 281 undercut_sl_entry = ttk.Entry(tab_undercut_left_top) 282 undercut_sl_entry.grid(padx=5, pady=5, row=1, column=1, sticky="nsew") 283 284 tk.Label(tab_undercut_left_top, text="PDX-value of your insert:").grid(padx=5, pady=5, row=2, column=0, sticky="nse") 285 pdx_entry = ttk.Entry(tab_undercut_left_top) 286 pdx_entry.grid(padx=5, pady=5, row=2, column=1, sticky="nsew") 287 288 # CALCULATIONS FOR EXTERNAL THREAD WITH UNDERCUT 289 290 def calc_undercut(): 291 undercut_output_box.config(state="normal") 292 undercut_output_box.delete("1.0", tk.END) 293 294 designation = undercut_designation_entry.get() 295 designation_parsed = self.parser.parse_designation(designation) 296 if isinstance(designation_parsed, str): 297 undercut_output_box.insert(tk.END, designation_parsed + "\n") 298 undercut_output_box.config(state="disabled") 299 return 300 d, pitch, grade, class_letter = designation_parsed 301 302 sl = undercut_sl_entry.get() 303 sl_parsed = self.parser.parse_sl(sl) 304 if isinstance(sl_parsed, str): 305 undercut_output_box.insert(tk.END, sl_parsed + "\n") 306 undercut_output_box.config(state="disabled") 307 return 308 s, l = sl_parsed 309 310 PDX = self.parser.validated(pdx_entry.get()) 311 if PDX is None: 312 undercut_output_box.insert(tk.END, "Invalid PDX-value!\n") 313 314 T_d_value = self.db_td.lookup_value_T_d(diameter=d, pitch=pitch, grade=grade) 315 if T_d_value is None: 316 undercut_output_box.insert(tk.END, "No T_d-value found in database!\n") 317 undercut_output_box.config(state="disabled") 318 return 319 320 es_value = self.db_es.lookup_value_es(pitch=pitch, class_letter=class_letter) 321 if es_value is None: 322 undercut_output_box.insert(tk.END, "No es-value found in database!\n") 323 undercut_output_box.config(state="disabled") 324 return 325 326 327 depth = ThreadCalculator.calc_depth(pitch, es_value, T_d_value) 328 fal = ThreadCalculator.cal_fal(pitch) 329 noc = ThreadCalculator.calc_noc(pitch) 330 331 # Display results 332 undercut_output_box.insert(tk.END, f"SPL: {s}\n") 333 undercut_output_box.insert(tk.END, f"DM1: {d}\n") 334 if PDX is None: 335 undercut_output_box.insert(tk.END, "FPL: Not Calculated\n") 336 else: 337 undercut_output_box.insert(tk.END, f"FPL: {s - l + 0.5 + PDX}\n") 338 undercut_output_box.insert(tk.END, f"APP: {pitch}\n") 339 if PDX is None: 340 undercut_output_box.insert(tk.END, "ROP: Not Calculated\n") 341 else: 342 undercut_output_box.insert(tk.END, f"ROP: g1-({0.5+PDX})\n") 343 undercut_output_box.insert(tk.END, f"TDEP: {depth:.4f}\n") 344 if fal is None: 345 undercut_output_box.insert(tk.END, f"FAL: {fal}, choose different pitch (0.5-6)!\n") 346 else: 347 undercut_output_box.insert(tk.END, f"FAL: {fal}\n") 348 undercut_output_box.insert(tk.END, f"IANG: 28\n") 349 if noc is None: 350 undercut_output_box.insert(tk.END, f"NRC: {noc}, choose different pitch (0.5-6)!\n") 351 else: 352 undercut_output_box.insert(tk.END, f"NRC: {noc-1}\n") 353 undercut_output_box.insert(tk.END, f"PIT: {pitch}\n") 354 undercut_output_box.insert(tk.END, f"VARI: 300103 (constant area!)\n") 355 356 undercut_output_box.config(state="disabled") 357 358 def clear_undercut_output(): 359 undercut_output_box.config(state="normal") 360 undercut_output_box.delete("1.0", tk.END) 361 undercut_output_box.config(state="disabled") 362 363 364 365 ttk.Button(tab_undercut_left_bottom, text="Calculate", command=calc_undercut).grid(padx=5, pady=5, row=0, column=0, sticky="sew") 366 367 ttk.Button(tab_undercut_left_bottom, text="Clear Output", command=clear_undercut_output).grid(padx=5, pady=5, row=0, column=1, sticky="sew") 368 369 undercut_output_box = tk.Text(tab_undercut_right, height=20, width=80) 370 undercut_output_box.grid(padx=5, pady=5, row=0, column=0, sticky="nsew") 371 undercut_output_box.config(state="disabled") # Read-only initially 372 373 return frame 374 375 376 377 378 379 380 # ---------------- INTERNAL THREAD ENVIRONMENT ------------------ 381 def build_int_env(self): 382 frame = ttk.Frame(self.container) 383 frame.place(relwidth=1, relheight=1) 384 385 ttk.Button(frame, text="← Back", command=lambda: self.show(self.main_menu)).pack(anchor="w", pady=5, padx=5) 386 387 notebook = ttk.Notebook(frame) 388 notebook.pack(expand=True, fill="both", padx=5, pady=10) 389 390 391 # --- TAB 1: CENTER DRILL --- # 392 tab_center_drill = ttk.Frame(notebook) 393 tab_center_drill.columnconfigure(0, weight=1, uniform="half") 394 tab_center_drill.columnconfigure(1, weight=1, uniform="half") 395 tab_center_drill.rowconfigure(0, weight=1) 396 397 notebook.add(tab_center_drill, text="Center Drill") 398 399 tab_center_drill_left = ttk.LabelFrame(tab_center_drill, text="Input") 400 tab_center_drill_left.grid(row=0, column=0, padx=5, pady=5, sticky="nsew") 401 tab_center_drill_left.columnconfigure(0, weight=1) 402 tab_center_drill_left.rowconfigure(1, weight=1) 403 tab_center_drill_left.rowconfigure(0, weight=1) 404 405 406 tab_center_drill_left_top = ttk.Frame(tab_center_drill_left) 407 tab_center_drill_left_top.grid(row=0, column=0, padx=5, pady=5, sticky="new") 408 tab_center_drill_left_top.columnconfigure(1, weight=1, uniform="half") 409 tab_center_drill_left_top.columnconfigure(0, weight=1, uniform="half") 410 411 412 413 tab_center_drill_left_bottom = ttk.Frame(tab_center_drill_left) 414 tab_center_drill_left_bottom.grid(row=1, column=0, padx=5, pady=5, sticky="sew") 415 tab_center_drill_left_bottom.columnconfigure(0, weight=1) 416 tab_center_drill_left_bottom.columnconfigure(1, weight=1) 417 418 419 tab_center_drill_right = ttk.LabelFrame(tab_center_drill, text="Output") 420 tab_center_drill_right.grid(row=0, column=1, padx=5, pady=5, sticky="nsew") 421 tab_center_drill_right.columnconfigure(0, weight=1) 422 tab_center_drill_right.rowconfigure(0, weight=1) 423 424 425 426 tk.Label(tab_center_drill_left_top, text="Designation:").grid(padx=5, pady=5, row=0, column=0, sticky="nse") 427 center_drill_designation_entry = ttk.Entry(tab_center_drill_left_top) 428 center_drill_designation_entry.grid(padx=5, pady=5, row=0, column=1, sticky="nsew") 429 430 tk.Label(tab_center_drill_left_top, text="Hole start point:").grid(padx=5, pady=5, row=1, column=0, sticky="nse") 431 center_drill_s_entry = ttk.Entry(tab_center_drill_left_top) 432 center_drill_s_entry.grid(padx=5, pady=5, row=1, column=1, sticky="nsew") 433 434 tk.Label(tab_center_drill_left_top, text="Center drill cone angle:").grid(padx=5, pady=5, row=2, column=0, sticky="nse") 435 center_drill_angle_entry = ttk.Entry(tab_center_drill_left_top) 436 center_drill_angle_entry.grid(padx=5, pady=5, row=2, column=1, sticky="nsew") 437 438 # CALCULATIONS FOR CENTER DRILL 439 440 def calc_center_drill(): 441 center_drill_output_box.config(state="normal") 442 center_drill_output_box.delete("1.0", tk.END) 443 444 designation = center_drill_designation_entry.get() 445 designation_parsed = self.parser.parse_designation(designation) 446 if isinstance(designation_parsed, str): 447 center_drill_output_box.insert(tk.END, designation_parsed + "\n") 448 center_drill_output_box.config(state="disabled") 449 return 450 d, pitch, grade, class_letter = designation_parsed 451 452 d2 = d - pitch 453 454 s = self.parser.validated(center_drill_s_entry.get()) 455 if s is None: 456 center_drill_output_box.insert(tk.END, "Invalid hole start point!\n") 457 center_drill_output_box.config(state="disabled") 458 return 459 460 461 a1 = self.parser.validated(center_drill_angle_entry.get()) 462 if a1 is None: 463 center_drill_output_box.insert(tk.END, "Invalid center drill cone angle!\n") 464 center_drill_output_box.config(state="disabled") 465 return 466 467 h1 = (0.65*d2)/(2*math.tan(math.radians(a1/2))) 468 469 # DISPLAY RESULTS 470 471 center_drill_output_box.insert(tk.END, f"RFP: {s}\n") 472 center_drill_output_box.insert(tk.END, f"DP: {s-h1: .5f}\n") 473 center_drill_output_box.config(state="disabled") 474 475 def clear_center_drill_output(): 476 center_drill_output_box.config(state="normal") 477 center_drill_output_box.delete("1.0", tk.END) 478 center_drill_output_box.config(state="disabled") 479 480 481 ttk.Button(tab_center_drill_left_bottom, text="Calculate", command=calc_center_drill).grid(padx=5, pady=5, row=0, column=0, sticky="sew") 482 483 ttk.Button(tab_center_drill_left_bottom, text="Clear Output", command=clear_center_drill_output).grid(padx=5, pady=5, row=0, column=1, sticky="sew") 484 485 486 center_drill_output_box = tk.Text(tab_center_drill_right, height=20, width=80) 487 center_drill_output_box.grid(padx=5, pady=5, row=0, column=0, sticky="nsew") 488 center_drill_output_box.config(state="disabled") # Read-only initially 489 490 491 492 493 # --- TAB 2: DEEP HOLE DRILL --- # 494 tab_deep_hole_drill = ttk.Frame(notebook) 495 tab_deep_hole_drill.columnconfigure(0, weight=1, uniform="half") 496 tab_deep_hole_drill.columnconfigure(1, weight=1, uniform="half") 497 tab_deep_hole_drill.rowconfigure(0, weight=1) 498 499 notebook.add(tab_deep_hole_drill, text="Deep Hole Drill") 500 501 tab_deep_hole_drill_left = ttk.LabelFrame(tab_deep_hole_drill, text="Input") 502 tab_deep_hole_drill_left.grid(row=0, column=0, padx=5, pady=5, sticky="nsew") 503 tab_deep_hole_drill_left.columnconfigure(0, weight=1) 504 tab_deep_hole_drill_left.rowconfigure(1, weight=1) 505 tab_deep_hole_drill_left.rowconfigure(0, weight=1) 506 tab_deep_hole_drill_left.rowconfigure(1, weight=1) 507 508 tab_deep_hole_drill_left_top = ttk.Frame(tab_deep_hole_drill_left) 509 tab_deep_hole_drill_left_top.grid(row=0, column=0, padx=5, pady=5, sticky="new") 510 tab_deep_hole_drill_left_top.columnconfigure(1, weight=1, uniform="half") 511 tab_deep_hole_drill_left_top.columnconfigure(0, weight=1, uniform="half") 512 513 tab_deep_hole_drill_left_bottom = ttk.Frame(tab_deep_hole_drill_left) 514 tab_deep_hole_drill_left_bottom.grid(row=1, column=0, padx=5, pady=5, sticky="sew") 515 tab_deep_hole_drill_left_bottom.columnconfigure(0, weight=1) 516 tab_deep_hole_drill_left_bottom.columnconfigure(1, weight=1) 517 518 tab_deep_hole_drill_right = ttk.LabelFrame(tab_deep_hole_drill, text="Output") 519 tab_deep_hole_drill_right.grid(row=0, column=1, padx=5, pady=5, sticky="nsew") 520 tab_deep_hole_drill_right.columnconfigure(0, weight=1) 521 tab_deep_hole_drill_right.rowconfigure(0, weight=1) 522 523 524 525 tk.Label(tab_deep_hole_drill_left_top, text="Designation:").grid(padx=5, pady=5, row=0, column=0, sticky="nse") 526 deep_hole_drill_designation_entry = ttk.Entry(tab_deep_hole_drill_left_top) 527 deep_hole_drill_designation_entry.grid(padx=5, pady=5, row=0, column=1, sticky="nsew") 528 529 tk.Label(tab_deep_hole_drill_left_top, text="Tapping tool form (e.g., C):").grid(padx=5, pady=5, row=1, column=0, sticky="nse") 530 deep_hole_drill_form_entry = ttk.Entry(tab_deep_hole_drill_left_top) 531 deep_hole_drill_form_entry.grid(padx=5, pady=5, row=1, column=1, sticky="nsew") 532 533 tk.Label(tab_deep_hole_drill_left_top, text="Hole start point and thread length:").grid(padx=5, pady=5, row=2, column=0, sticky="nse") 534 deep_hole_drill_sl_entry = ttk.Entry(tab_deep_hole_drill_left_top) 535 deep_hole_drill_sl_entry.grid(padx=5, pady=5, row=2, column=1, sticky="nsew") 536 537 tk.Label(tab_deep_hole_drill_left_top, text="Deep hole drill cone angle:").grid(padx=5, pady=5, row=3, column=0, sticky="nse") 538 deep_hole_drill_angle_entry = ttk.Entry(tab_deep_hole_drill_left_top) 539 deep_hole_drill_angle_entry.grid(padx=5, pady=5, row=3, column=1, sticky="nsew") 540 541 # CALCULATIONS FOR DEEP HOLE DRILLING 542 543 def calc_deep_hole_drill(): 544 deep_hole_drill_output_box.config(state="normal") 545 deep_hole_drill_output_box.delete("1.0", tk.END) 546 547 designation = deep_hole_drill_designation_entry.get() 548 designation_parsed = self.parser.parse_designation(designation) 549 if isinstance(designation_parsed, str): 550 deep_hole_drill_output_box.insert(tk.END, designation_parsed + "\n") 551 deep_hole_drill_output_box.config(state="disabled") 552 return 553 d, pitch, grade, class_letter = designation_parsed 554 555 d2 = d - pitch 556 557 form = deep_hole_drill_form_entry.get().lower() 558 form_range = { 559 "a": 8, 560 "b": 5, 561 "c": 3, 562 "d": 5, 563 "e": 2 564 } 565 if not isinstance(form, str): 566 deep_hole_drill_output_box.insert(tk.END, "Invalid type!\n") 567 deep_hole_drill_output_box.config(state="disabled") 568 return 569 elif form not in form_range: 570 deep_hole_drill_output_box.insert(tk.END, "Entered tool form not found!\n") 571 deep_hole_drill_output_box.config(state="disabled") 572 return 573 k = form_range.get(form) 574 575 sl = deep_hole_drill_sl_entry.get() 576 sl_parsed = self.parser.parse_sl(sl) 577 if isinstance(sl_parsed, str): 578 deep_hole_drill_output_box.insert(tk.END, sl_parsed + "\n") 579 deep_hole_drill_output_box.config(state="disabled") 580 return 581 s, l = sl_parsed 582 583 a2 = self.parser.validated(deep_hole_drill_angle_entry.get()) 584 if a2 is None: 585 deep_hole_drill_output_box.insert(tk.END, "Invalid deep hole drill cone angle!\n") 586 deep_hole_drill_output_box.config(state="disabled") 587 return 588 589 h_2 = ThreadCalculator.half_ceil(l + (k+2)*pitch + (d2)/(2*math.tan(math.radians(a2/2)))) 590 h2 = s - h_2 591 592 deep_hole_drill_output_box.insert(tk.END, f"RFP: {s}\n") 593 deep_hole_drill_output_box.insert(tk.END, f"DP: {h2: .3f}\n") 594 fdep = ThreadCalculator.depth_per_storke(h_2) 595 if fdep is None: 596 deep_hole_drill_output_box.insert(tk.END, "FDEP: Invalid depth!\n") 597 else: 598 deep_hole_drill_output_box.insert(tk.END, f"FDEP: {s - fdep}\n") 599 deep_hole_drill_output_box.config(state="disabled") 600 601 def clear_deep_hole_drill_output(): 602 deep_hole_drill_output_box.config(state="normal") 603 deep_hole_drill_output_box.delete("1.0", tk.END) 604 deep_hole_drill_output_box.config(state="disabled") 605 606 def deep_hole_drill_get_data(): 607 if center_drill_designation_entry.get(): 608 deep_hole_drill_designation_entry.delete(0, tk.END) 609 deep_hole_drill_designation_entry.insert(0, center_drill_designation_entry.get()) 610 if center_drill_s_entry.get(): 611 deep_hole_drill_sl_entry.delete(0, tk.END) 612 deep_hole_drill_sl_entry.insert(0, center_drill_s_entry.get()+",") 613 614 615 ttk.Button(tab_deep_hole_drill_left_bottom, text="Get Data", command=deep_hole_drill_get_data).grid(padx=5, pady=5, row=0, column=0, sticky="sew") 616 617 ttk.Button(tab_deep_hole_drill_left_bottom, text="Calculate", command=calc_deep_hole_drill).grid(padx=5, pady=5, row=1, column=0, sticky="sew") 618 ttk.Button(tab_deep_hole_drill_left_bottom, text="Clear Output", command=clear_deep_hole_drill_output).grid(padx=5, pady=5, row=1, column=1, sticky="sew") 619 620 621 deep_hole_drill_output_box = tk.Text(tab_deep_hole_drill_right, height=20, width=80) 622 deep_hole_drill_output_box.grid(padx=5, pady=5, row=0, column=0, sticky="nsew") 623 deep_hole_drill_output_box.config(state="disabled") # Read-only initially 624 625 626 627 # --- TAB 3: TAPPING --- # 628 tab_tapping = ttk.Frame(notebook) 629 tab_tapping.columnconfigure(0, weight=1, uniform="half") 630 tab_tapping.columnconfigure(1, weight=1, uniform="half") 631 tab_tapping.rowconfigure(0, weight=1) 632 633 notebook.add(tab_tapping, text="Tapping") 634 635 tab_tapping_left = ttk.LabelFrame(tab_tapping, text="Input") 636 tab_tapping_left.grid(row=0, column=0, padx=5, pady=5, sticky="nsew") 637 tab_tapping_left.columnconfigure(0, weight=1) 638 tab_tapping_left.rowconfigure(1, weight=1) 639 tab_tapping_left.rowconfigure(0, weight=1) 640 tab_tapping_left.rowconfigure(1, weight=1) 641 642 tab_tapping_left_top = ttk.Frame(tab_tapping_left) 643 tab_tapping_left_top.grid(row=0, column=0, padx=5, pady=5, sticky="new") 644 tab_tapping_left_top.columnconfigure(1, weight=1, uniform="half") 645 tab_tapping_left_top.columnconfigure(0, weight=1, uniform="half") 646 647 648 tab_tapping_left_bottom = ttk.Frame(tab_tapping_left) 649 tab_tapping_left_bottom.grid(row=1, column=0, padx=5, pady=5, sticky="sew") 650 tab_tapping_left_bottom.columnconfigure(0, weight=1) 651 tab_tapping_left_bottom.columnconfigure(1, weight=1) 652 653 tab_tapping_right = ttk.LabelFrame(tab_tapping, text="Output") 654 tab_tapping_right.grid(row=0, column=1, padx=5, pady=5, sticky="nsew") 655 tab_tapping_right.columnconfigure(0, weight=1) 656 tab_tapping_right.rowconfigure(0, weight=1) 657 658 659 tk.Label(tab_tapping_left_top, text="Designation:").grid(padx=5, pady=5, row=0, column=0, sticky="nse") 660 tapping_designation_entry = ttk.Entry(tab_tapping_left_top) 661 tapping_designation_entry.grid(padx=5, pady=5, row=0, column=1, sticky="nsew") 662 663 tk.Label(tab_tapping_left_top, text="Tapping tool form (e.g., C):").grid(padx=5, pady=5, row=1, column=0, sticky="nse") 664 tapping_form_entry = ttk.Entry(tab_tapping_left_top) 665 tapping_form_entry.grid(padx=5, pady=5, row=1, column=1, sticky="nsew") 666 667 tk.Label(tab_tapping_left_top, text="Hole start point and thread length:").grid(padx=5, pady=5, row=2, column=0, sticky="nse") 668 tapping_sl_entry = ttk.Entry(tab_tapping_left_top) 669 tapping_sl_entry.grid(padx=5, pady=5, row=2, column=1, sticky="nsew") 670 671 # CALCULATIONS FOR TAPPING 672 673 def calc_tapping(): 674 tapping_output_box.config(state="normal") 675 tapping_output_box.delete("1.0", tk.END) 676 677 designation = tapping_designation_entry.get() 678 designation_parsed = self.parser.parse_designation(designation) 679 if isinstance(designation_parsed, str): 680 tapping_output_box.insert(tk.END, designation_parsed + "\n") 681 tapping_output_box.config(state="disabled") 682 return 683 d, pitch, grade, class_letter = designation_parsed 684 685 form = tapping_form_entry.get().lower() 686 form_range = { 687 "a": 8, 688 "b": 5, 689 "c": 3, 690 "d": 5, 691 "e": 2 692 } 693 if not isinstance(form, str): 694 tapping_output_box.insert(tk.END, "Invalid type!\n") 695 tapping_output_box.config(state="disabled") 696 return 697 elif form not in form_range: 698 tapping_output_box.insert(tk.END, "Entered tool form not found!\n") 699 tapping_output_box.config(state="disabled") 700 return 701 k = form_range.get(form) 702 703 sl = tapping_sl_entry.get() 704 sl_parsed = self.parser.parse_sl(sl) 705 if isinstance(sl_parsed, str): 706 tapping_output_box.insert(tk.END, sl_parsed + "\n") 707 tapping_output_box.config(state="disabled") 708 return 709 s, l = sl_parsed 710 711 h4 = s - (l + k*pitch) 712 713 tapping_output_box.insert(tk.END, f"RFP: {s}\n") 714 tapping_output_box.insert(tk.END, f"DP: {h4}\n") 715 tapping_output_box.insert(tk.END, "SDAC: 5\n") 716 tapping_output_box.insert(tk.END, f"PIT: {pitch}\n") 717 718 719 tapping_output_box.config(state="disabled") 720 721 def clear_tapping_output(): 722 tapping_output_box.config(state="normal") 723 tapping_output_box.delete("1.0", tk.END) 724 tapping_output_box.config(state="disabled") 725 726 def get_tapping_data(): 727 if deep_hole_drill_designation_entry.get(): 728 tapping_designation_entry.delete(0, tk.END) 729 tapping_designation_entry.insert(0, deep_hole_drill_designation_entry.get()) 730 731 if (not deep_hole_drill_designation_entry.get()) and center_drill_designation_entry.get(): 732 tapping_designation_entry.delete(0, tk.END) 733 tapping_designation_entry.insert(0, center_drill_designation_entry.get()) 734 735 if (not deep_hole_drill_sl_entry.get()) and center_drill_s_entry.get(): 736 tapping_sl_entry.delete(0, tk.END) 737 tapping_sl_entry.insert(0, center_drill_s_entry.get()+",") 738 739 if deep_hole_drill_form_entry.get(): 740 tapping_form_entry.delete(0, tk.END) 741 tapping_form_entry.insert(0, deep_hole_drill_form_entry.get()) 742 743 if deep_hole_drill_sl_entry.get(): 744 tapping_sl_entry.delete(0, tk.END) 745 tapping_sl_entry.insert(0, deep_hole_drill_sl_entry.get()) 746 747 ttk.Button(tab_tapping_left_bottom, text="Get Data", command=get_tapping_data).grid(padx=5, pady=5, row=0, column=0, sticky="sew") 748 749 ttk.Button(tab_tapping_left_bottom, text="Calculate", command=calc_tapping).grid(padx=5, pady=5, row=1, column=0, sticky="sew") 750 751 ttk.Button(tab_tapping_left_bottom, text="Clear Output", command=clear_tapping_output).grid(padx=5, pady=5, row=1, column=1, sticky="sew") 752 753 754 tapping_output_box = tk.Text(tab_tapping_right) 755 tapping_output_box.grid(padx=5, pady=5, row=0, column=0, sticky="nsew") 756 tapping_output_box.config(state="disabled") # Read-only initially 757 758 759 760 return frame 761 762 763 764 765 766 767 768 769 if __name__ == "__main__": 770 app = App() 771 app.mainloop() 772