RCBeamdesign / beam_design_app.py
Sompote's picture
Upload 4 files
0be7e4d verified
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()