(10-6-01)传感器布局分析与优化系统:主程序(1)设置仿真参数

10.8  主程序

通过前面的介绍,本项目需要的传感器模拟功能基本介绍完毕。在本节的内容中,将详细讲解调用前面所介绍模块实现主程序的过程。

10.8.1  设置仿真参数

编写文件utils/gui.py,这是一个基于customtkinter和tkinter库的GUI类,用于收集用户的仿真参数和设置。用户可以选择仿真环境的尺寸、单元格大小、是否使用扩展模式,选择车辆的3D模型文件,设置仿真结果保存路径和名称,以及选择在Z方向上的交叉截面数量和间距。用户通过在界面上输入和确认这些参数,最终获取输入数据以启动应用程序。整个界面分为左右两列,右列包含关于仿真设置和车辆3D模型的信息,左列包含有关保存路径、仿真名称和交叉截面设置的信息。文件utils/gui.py的具体实现流程如下所示。

(1)定义函数set_grid_data,功能是从用户输入中设置仿真网格的维度、单元格大小和扩展模式,并在界面上显示相应信息。

ctk.set_appearance_mode("light")
ctk.set_default_color_theme("dark-blue")
 
class GUI:
    def set_grid_data(self):
        self.data["dim_x"] = int(self.dimx_line.get())
        self.data["dim_y"] = int(self.dimy_line.get())
        self.data["dim_z"] = int(self.dimz_line.get())
        self.data["spacing"] = float(self.spacing_line.get())
        self.data["advanced"] = self.checkbox_var.get()
        if (
            self.data["dim_x"]
            and self.data["dim_y"]
            and self.data["dim_z"]
            and self.data["spacing"]
            and self.data["advanced"]
        ):
            self.display_grid.delete(0, ctk.END)
            self.display_grid.insert(
                ctk.END,
                f"Your Simulation will contain an environment of {self.data['dim_x']}m x {self.data['dim_y']}m x {self.data['dim_z']}m and with a cell size of {self.data['spacing']}m^3 in extended mode",
            )
        if (
            self.data["dim_x"]
            and self.data["dim_y"]
            and self.data["dim_z"]
            and self.data["spacing"]
            and not self.data["advanced"]
        ):
            self.display_grid.delete(0, ctk.END)
            self.display_grid.insert(
                ctk.END,
                f"Your Simulation will contain an environment of {self.data['dim_x']}m x {self.data['dim_y']}m x {self.data['dim_z']}m and with a cell size of {self.data['spacing']}m^3 in normal mode",
            )

(2)定义函数set_path,功能是允许用户选择保存仿真结果的路径,并在界面上显示所选路径。

    def set_path(self):
        self.data["save_path"] = ctk.filedialog.askdirectory()
        if self.data["save_path"]:
            results_path = self.data["save_path"]
            self.path_display.delete(0, ctk.END)
            self.path_display.insert(ctk.END, results_path)

(3)定义函数set_name,功能是获取用户输入的仿真名称,并在界面上显示确认信息。

    def set_name(self):
        self.data["folder_name"] = self.entry_line.get()
        if self.data["folder_name"]:
            self.display_line.delete(0, ctk.END)
            self.display_line.insert(
                ctk.END, f"{self.data['folder_name']} is the name of your simulation"
            )

(4)定义函数set_vehicle,功能是允许用户选择车辆的3D模型文件,并在界面上显示所选文件路径。

    def set_vehicle(self):
        self.data["vehicle_path"] = ctk.filedialog.askopenfilename()
        if self.data["vehicle_path"]:
            self.vehicle_display.delete(0, ctk.END)
            self.vehicle_display.insert(ctk.END, self.data["vehicle_path"])

(5)定义函数set_slices,功能是从用户输入中设置在Z方向上的交叉截面数量和间距,并在界面上显示相应信息。

    def set_slices(self):
        self.data["slice_number"] = int(self.number_line.get())
        self.data["slice_distance"] = float(self.distance_line.get())
        if self.data["slice_number"] and self.data["slice_distance"]:
            self.display_slices.delete(0, ctk.END)
            self.display_slices.insert(
                ctk.END,
                f"Your Simulation will contain {self.data['slice_number']} cross-sections in an interval of "
                f"{self.data['slice_distance']}m in z-direction",
            )

(6)定义函数__init__,功能是初始化GUI类的实例,创建CTk根窗口和数据字典。

    def __init__(self):
        self.root = ctk.CTk()
        self.data = {}
        self.setup_ui()

(7)定义函数setup_ui,功能是配置GUI界面的各个部分,包括仿真网格设置、车辆3D模型选择、结果保存路径和名称设置以及交叉截面设置。

    def setup_ui(self):
        left_column = ctk.CTkFrame(self.root)
        left_column.pack(side="left")
        right_column = ctk.CTkFrame(self.root)
        right_column.pack(side="left")
 
        # ---- frame for the grid data -------
        frame_grid = ctk.CTkFrame(master=right_column)
        frame_grid.pack(pady=15, padx=15, fill="both", expand=True)
        title_grid = ctk.CTkLabel(
            master=frame_grid, text="Simulation settings", font=("Roboto", 18), pady=10
        )
        title_grid.grid(row=0, column=0, sticky="ew", columnspan=3)
        line1 = ttk.Separator(master=frame_grid, orient="horizontal")
        line1.grid(row=1, column=0, sticky="ew", columnspan=3)
        entry0 = ctk.CTkLabel(
            master=frame_grid,
            pady=5,
            text="In this section you select the settings for the simulation. The environment is centered at (0, 0, 0).",
        )
        entry0.grid(row=2, column=0, sticky="ew", columnspan=3)
        line11 = ttk.Separator(master=frame_grid, orient="horizontal")
        line11.grid(row=3, column=0, sticky="ew", columnspan=3)
        entry00 = ctk.CTkLabel(
            master=frame_grid,
            pady=5,
            text="Please enter the the dimensions of the environment you want to simulate in meters (integer value):",
        )
        entry00.grid(row=4, column=0, sticky="ew", columnspan=3)
        line12 = ttk.Separator(master=frame_grid, orient="horizontal")
        line12.grid(row=7, column=0, sticky="ew", columnspan=3, pady=5)
        entry01 = ctk.CTkLabel(
            master=frame_grid,
            pady=5,
            text="Please enter the edge length of the cells in meters (float value, e.g. 0.12):",
        )
        entry01.grid(row=8, column=0, sticky="ew", columnspan=3)
        self.dimx_line = ctk.CTkEntry(master=frame_grid, width=100)
        self.dimx_line.grid(row=6, column=0)
        self.dimy_line = ctk.CTkEntry(master=frame_grid, width=100)
        self.dimy_line.grid(row=6, column=1)
        self.dimz_line = ctk.CTkEntry(master=frame_grid, width=100)
        self.dimz_line.grid(row=6, column=2)
        title_dimx = ctk.CTkLabel(master=frame_grid, text="Dimension in x-Direction:")
        title_dimx.grid(row=5, column=0)
        title_dimy = ctk.CTkLabel(master=frame_grid, text="Dimension in y-Direction:")
        title_dimy.grid(row=5, column=1)
        title_dimz = ctk.CTkLabel(master=frame_grid, text="Dimension in z-Direction:")
        title_dimz.grid(row=5, column=2)
        title_spacing = ctk.CTkLabel(master=frame_grid, text="Edge length of cells:")
        title_spacing.grid(row=9, column=1)
        self.spacing_line = ctk.CTkEntry(master=frame_grid, width=100)
        self.spacing_line.grid(row=10, column=1, pady=5)
 
        entry02 = ctk.CTkLabel(
            master=frame_grid,
            pady=5,
            text="Please check the box if you want to use extended mode and click confirm:",
        )
        entry02.grid(row=11, column=0, sticky="ew", columnspan=3)
        self.checkbox_var = tk.BooleanVar()
        checkbox = ctk.CTkCheckBox(
            frame_grid, text="Extended mode", variable=self.checkbox_var
        )
        checkbox.grid(row=12, column=1)
        confirm_button0 = ctk.CTkButton(
            master=frame_grid, text="Confirm", command=self.set_grid_data
        )
        confirm_button0.grid(row=13, column=1, pady=5)
        self.display_grid = ctk.CTkEntry(master=frame_grid, width=700)
        self.display_grid.grid(row=14, column=0, sticky="ew", columnspan=3, pady=5)
 
        # ---- frame for the 3d model for the vehicle  ------
        frame_vehicle = ctk.CTkFrame(master=right_column)
        frame_vehicle.pack(pady=15, padx=15, fill="both", expand=True)
        title_vehicle = ctk.CTkLabel(
            master=frame_vehicle,
            text="Select 3-D Model for Vehicle",
            font=("Roboto", 18),
            pady=10,
        )
        title_vehicle.pack()
        line2 = ttk.Separator(master=frame_vehicle, orient="horizontal")
        line2.pack(fill="x")
        entry3 = ctk.CTkLabel(
            master=frame_vehicle,
            pady=5,
            text="Please select the 3-D Model, that the application should load"
            " and use as the vehicle",
        )
        entry3.pack()
        browse_button2 = ctk.CTkButton(
            master=frame_vehicle, text="Browse", command=self.set_vehicle
        )
        browse_button2.pack()
        entry4 = ctk.CTkLabel(
            master=frame_vehicle, text="The following 3-D Model is currently selected:"
        )
        entry4.pack()
        self.vehicle_display = ctk.CTkEntry(master=frame_vehicle, width=500)
        self.vehicle_display.pack(pady=5)
 
        # ----- frame for the name and path  -------
        frame_path = ctk.CTkFrame(master=left_column)
        frame_path.pack(pady=15, padx=15, fill="both", expand=True)
        title_save = ctk.CTkLabel(
            master=frame_path, text="Save results", font=("Roboto", 18), pady=10
        )
        title_save.pack()
        line1 = ttk.Separator(master=frame_path, orient="horizontal")
        line1.pack(fill="x")
        entry1 = ctk.CTkLabel(
            master=frame_path,
            pady=5,
            text="Please select, where the simulation results should be saved.\n"
            "If no path is selected the results will be saved to simulation_"
            "results in the applications directory\n",
        )
        entry1.pack()
        browse_button = ctk.CTkButton(
            master=frame_path, text="Browse", command=self.set_path
        )
        browse_button.pack()
        entry2 = ctk.CTkLabel(
            master=frame_path, text="The following path is currently selected:"
        )
        entry2.pack()
        self.path_display = ctk.CTkEntry(master=frame_path, width=500)
        self.path_display.pack(pady=5)
 
        text = ctk.CTkLabel(
            master=frame_path,
            text="Please enter the name for the simulation and click confirm:",
        )
        text.pack()
        self.entry_line = ctk.CTkEntry(master=frame_path, width=500)
        self.entry_line.pack(pady=5)
        confirm_button = ctk.CTkButton(
            master=frame_path, text="Confirm", command=self.set_name
        )
        confirm_button.pack()
        self.display_line = ctk.CTkEntry(master=frame_path, width=500)
        self.display_line.pack(pady=5)
        text2 = ctk.CTkLabel(
            master=frame_path,
            text="If no name is entered, a timestamp is used as a name.",
        )
        text2.pack()
 
        # ----- frame for the slices  ------
        frame_slices = ctk.CTkFrame(master=left_column)
        frame_slices.pack(pady=15, padx=15, fill="both", expand=True)
        title_slices = ctk.CTkLabel(
            master=frame_slices,
            text="Select cross-sections in z-direction",
            font=("Roboto", 18),
            pady=10,
        )
        title_slices.pack()
        line3 = ttk.Separator(master=frame_slices, orient="horizontal")
        line3.pack(fill="x")
        entry5 = ctk.CTkLabel(
            master=frame_slices,
            pady=5,
            text="The first cross section is cut at z=0m.\nPlease enter the "
            "number of cross sections for your simulation(integer value):",
        )
        entry5.pack()
        self.number_line = ctk.CTkEntry(master=frame_slices, width=500)
        self.number_line.pack(pady=5)
        entry6 = ctk.CTkLabel(
            master=frame_slices,
            pady=5,
            text="Please enter the distance between each cross section in meters(float value, e.g. 0.35) and "
            "click confirm:",
        )
        entry6.pack()
        self.distance_line = ctk.CTkEntry(master=frame_slices, width=500)
        self.distance_line.pack(pady=5)
        confirm_button2 = ctk.CTkButton(
            master=frame_slices, text="Confirm", command=self.set_slices
        )
        confirm_button2.pack()
        self.display_slices = ctk.CTkEntry(master=frame_slices, width=500)
        self.display_slices.pack(pady=5)
 
        final_text = ctk.CTkLabel(
            master=right_column,
            text="To start the application, recheck your inputs and close this window",
            font=("Roboto", 18),
            pady=5,
        )
        final_text.pack()

(8)定义函数get_inputs,功能是返回用户输入的仿真参数和设置的数据字典。

    def get_inputs(self):
        return self.data

(9)定义函数run,功能是启动GUI应用程序,进入主事件循环,等待用户操作。

    def run(self):
        self.root.mainloop()

未完待续

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农三叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值