Spaces:
Sleeping
Sleeping
| import tkinter as tk | |
| from tkinter import ttk, messagebox, scrolledtext | |
| from continuous_beam import ContinuousBeam | |
| import matplotlib.pyplot as plt | |
| from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg | |
| import numpy as np | |
| class BeamDesignApp: | |
| def __init__(self, root): | |
| self.root = root | |
| self.root.title("Continuous Beam RC Design - ACI Code") | |
| self.root.geometry("1200x800") | |
| self.beam = ContinuousBeam() | |
| self.setup_ui() | |
| def setup_ui(self): | |
| # Create main frame | |
| main_frame = ttk.Frame(self.root, padding="10") | |
| main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S)) | |
| # Configure grid weights | |
| self.root.columnconfigure(0, weight=1) | |
| self.root.rowconfigure(0, weight=1) | |
| main_frame.columnconfigure(1, weight=1) | |
| main_frame.rowconfigure(3, weight=1) | |
| # Title | |
| title_label = ttk.Label(main_frame, text="Continuous Beam RC Design", | |
| font=('Arial', 16, 'bold')) | |
| title_label.grid(row=0, column=0, columnspan=2, pady=(0, 20)) | |
| # Input frame | |
| input_frame = ttk.LabelFrame(main_frame, text="Beam Properties", padding="10") | |
| input_frame.grid(row=1, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10)) | |
| # Beam properties | |
| ttk.Label(input_frame, text="Beam Width (mm):").grid(row=0, column=0, sticky=tk.W) | |
| self.width_var = tk.StringVar(value="300") | |
| ttk.Entry(input_frame, textvariable=self.width_var, width=10).grid(row=0, column=1, sticky=tk.W, padx=(5, 20)) | |
| ttk.Label(input_frame, text="Beam Depth (mm):").grid(row=0, column=2, sticky=tk.W) | |
| self.depth_var = tk.StringVar(value="500") | |
| ttk.Entry(input_frame, textvariable=self.depth_var, width=10).grid(row=0, column=3, sticky=tk.W, padx=(5, 20)) | |
| ttk.Label(input_frame, text="f'c (MPa):").grid(row=1, column=0, sticky=tk.W) | |
| self.fc_var = tk.StringVar(value="28") | |
| ttk.Entry(input_frame, textvariable=self.fc_var, width=10).grid(row=1, column=1, sticky=tk.W, padx=(5, 20)) | |
| ttk.Label(input_frame, text="fy (MPa):").grid(row=1, column=2, sticky=tk.W) | |
| self.fy_var = tk.StringVar(value="420") | |
| ttk.Entry(input_frame, textvariable=self.fy_var, width=10).grid(row=1, column=3, sticky=tk.W, padx=(5, 20)) | |
| ttk.Label(input_frame, text="Cover (mm):").grid(row=2, column=0, sticky=tk.W) | |
| self.cover_var = tk.StringVar(value="40") | |
| ttk.Entry(input_frame, textvariable=self.cover_var, width=10).grid(row=2, column=1, sticky=tk.W, padx=(5, 20)) | |
| # Spans frame | |
| spans_frame = ttk.LabelFrame(main_frame, text="Spans Configuration", padding="10") | |
| spans_frame.grid(row=2, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10)) | |
| # Span input | |
| ttk.Label(spans_frame, text="Span Length (m):").grid(row=0, column=0, sticky=tk.W) | |
| self.span_length_var = tk.StringVar(value="6.0") | |
| ttk.Entry(spans_frame, textvariable=self.span_length_var, width=10).grid(row=0, column=1, sticky=tk.W, padx=(5, 20)) | |
| ttk.Label(spans_frame, text="Distributed Load (kN/m):").grid(row=0, column=2, sticky=tk.W) | |
| self.load_var = tk.StringVar(value="25.0") | |
| ttk.Entry(spans_frame, textvariable=self.load_var, width=10).grid(row=0, column=3, sticky=tk.W, padx=(5, 20)) | |
| # Buttons | |
| button_frame = ttk.Frame(spans_frame) | |
| button_frame.grid(row=1, column=0, columnspan=4, pady=10) | |
| ttk.Button(button_frame, text="Add Span", command=self.add_span).pack(side=tk.LEFT, padx=(0, 10)) | |
| ttk.Button(button_frame, text="Clear All", command=self.clear_spans).pack(side=tk.LEFT, padx=(0, 10)) | |
| ttk.Button(button_frame, text="Design Beam", command=self.design_beam).pack(side=tk.LEFT, padx=(0, 10)) | |
| # Spans list | |
| self.spans_listbox = tk.Listbox(spans_frame, height=4) | |
| self.spans_listbox.grid(row=2, column=0, columnspan=4, sticky=(tk.W, tk.E), pady=(10, 0)) | |
| spans_frame.columnconfigure(0, weight=1) | |
| spans_frame.columnconfigure(1, weight=1) | |
| spans_frame.columnconfigure(2, weight=1) | |
| spans_frame.columnconfigure(3, weight=1) | |
| # Results frame | |
| results_frame = ttk.LabelFrame(main_frame, text="Design Results", padding="10") | |
| results_frame.grid(row=3, column=0, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S)) | |
| results_frame.columnconfigure(0, weight=1) | |
| results_frame.rowconfigure(0, weight=1) | |
| # Results text area | |
| self.results_text = scrolledtext.ScrolledText(results_frame, width=80, height=20, font=('Courier', 9)) | |
| self.results_text.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S)) | |
| def add_span(self): | |
| try: | |
| length = float(self.span_length_var.get()) | |
| load = float(self.load_var.get()) | |
| if length <= 0 or load < 0: | |
| messagebox.showerror("Error", "Please enter valid values (length > 0, load >= 0)") | |
| return | |
| self.beam.add_span(length, load) | |
| # Update spans list | |
| span_text = f"Span {len(self.beam.spans)}: L={length}m, w={load}kN/m" | |
| self.spans_listbox.insert(tk.END, span_text) | |
| # Clear input fields | |
| self.span_length_var.set("") | |
| self.load_var.set("") | |
| except ValueError: | |
| messagebox.showerror("Error", "Please enter valid numeric values") | |
| def clear_spans(self): | |
| self.beam = ContinuousBeam() | |
| self.spans_listbox.delete(0, tk.END) | |
| self.results_text.delete('1.0', tk.END) | |
| def design_beam(self): | |
| if not self.beam.spans: | |
| messagebox.showwarning("Warning", "Please add at least one span") | |
| return | |
| try: | |
| # Update beam properties | |
| self.beam.beam_width = float(self.width_var.get()) | |
| self.beam.beam_depth = float(self.depth_var.get()) | |
| self.beam.fc = float(self.fc_var.get()) | |
| self.beam.fy = float(self.fy_var.get()) | |
| self.beam.cover = float(self.cover_var.get()) | |
| self.beam.d = self.beam.beam_depth - self.beam.cover | |
| # Perform design | |
| design_results = self.beam.design_beam() | |
| # Generate and display report | |
| report = self.beam.generate_report(design_results) | |
| self.results_text.delete('1.0', tk.END) | |
| self.results_text.insert('1.0', report) | |
| # Show summary dialog | |
| self.show_summary(design_results) | |
| except Exception as e: | |
| messagebox.showerror("Error", f"Design calculation failed: {str(e)}") | |
| def show_summary(self, design_results): | |
| """Show design summary in a popup window""" | |
| summary_window = tk.Toplevel(self.root) | |
| summary_window.title("Design Summary") | |
| summary_window.geometry("600x400") | |
| # Create treeview for summary | |
| tree = ttk.Treeview(summary_window, columns=('Span', 'Location', 'Moment', 'Reinforcement', 'Shear', 'Stirrups')) | |
| tree.heading('#0', text='', anchor='w') | |
| tree.heading('Span', text='Span') | |
| tree.heading('Location', text='Location') | |
| tree.heading('Moment', text='Moment (kN-m)') | |
| tree.heading('Reinforcement', text='Reinforcement') | |
| tree.heading('Shear', text='Shear (kN)') | |
| tree.heading('Stirrups', text='Stirrups') | |
| tree.column('#0', width=0, stretch=False) | |
| tree.column('Span', width=60) | |
| tree.column('Location', width=100) | |
| tree.column('Moment', width=100) | |
| tree.column('Reinforcement', width=120) | |
| tree.column('Shear', width=80) | |
| tree.column('Stirrups', width=120) | |
| for span_data in design_results: | |
| span_num = span_data['span'] | |
| for i, (reinf, stirrup) in enumerate(zip(span_data['reinforcement'], span_data['stirrups'])): | |
| if reinf['moment'] != 0 or stirrup['shear'] != 0: | |
| tree.insert('', 'end', values=( | |
| span_num if i == 0 else '', | |
| reinf['location'], | |
| f"{reinf['moment']:.2f}" if reinf['moment'] != 0 else '-', | |
| reinf['bars'] if reinf['moment'] != 0 else '-', | |
| f"{stirrup['shear']:.2f}" if stirrup['shear'] != 0 else '-', | |
| stirrup['stirrup_spacing'] if stirrup['shear'] != 0 else '-' | |
| )) | |
| tree.pack(expand=True, fill='both', padx=10, pady=10) | |
| # Close button | |
| ttk.Button(summary_window, text="Close", | |
| command=summary_window.destroy).pack(pady=10) | |
| def main(): | |
| root = tk.Tk() | |
| app = BeamDesignApp(root) | |
| root.mainloop() | |
| if __name__ == "__main__": | |
| main() |