PySimpleGUI制作简易停车场管理系统

此文章旨在记录自己学习内容,内容十分基础,还有许多不完善的多体谅 :)


停车场管理系统:

若车辆到达,则显示汽车在停车场内或便道上的停车位置;若车辆离去,则显示汽车在停车场内停留的时间和应缴纳的费用,在便道停留不收费。

1 PySimpleGUI

1.1 简介

PySimpleGUI是一个Python库,专为简化图形用户界面(GUI)的开发而设计。

它提供了许多预定义的窗口和元素,可以使用PySimpleGUI来创建窗口、按钮、文本框、输入框等,使得创建简单的GUI应用程序变得容易。

1.2下载

pip install PySimpleGUI

利用pip命令下载安装,请注意,确保你的计算机上已经安装了Python和pip。pip是Python的包管理工具,用于安装和管理Python包。

2 代码讲解

2.1 库引用

import PySimpleGUI as sg
from datetime import datetime
from collections import deque

该程序需要引入PySimpleGUIdatetimecollections三个库,其中再简要介绍一下另外两个库。

datetime库

  1.  这是Python标准库中的一个模块,用于处理日期和时间。
  2. 使用datetime模块来获取当前日期和时间,执行日期和时间运算,以及格式化日期和时间。

collections库

  1. collections是 Python 的一个标准库,它提供了一些额外的容器类型,以补充 Python 内置的容器类型。这些额外的容器类型提供了更多的功能和灵活性,可以帮助你更高效地解决问题。
  2. 使用deque模块代表双端队列,支持从两端添加和删除元素。deque支持从两端添加(append)和删除(pop)元素,这使得它非常适合用作滑动窗口、队列或栈等数据结构。

2.2 创建停车场类

class ParkingLotSystem:
    def __init__(self, capacity):
        self.capacity = capacity
        self.parking_lot = []  # 使用列表作为来模拟停车场
        self.lane = deque()  # 使用deque作为队列来模拟便道
        self.car_info = {}  # 存储车辆信息的字典,键为车牌号码,值为(到达时间,停车位置)元组

初始化(_init_方法):

  • self.capacity:表示停车场的容量,即停车场最多可以停放多少辆车。
  • self.parking_lot:是一个列表(list),用来存储已经停放在停车场内的车辆的信息。
  • self.lane:是一个双端队列(deque),用来模拟停车场出口的车道,车辆会按照进入的顺序排列在这个车道上等待进入停车场。
  • self.car_info:是一个字典(dict),用来储存每辆车的信息,比如车牌号和停车时间等。

2.3 主要功能函数

    def process_event(self, event_type, car_id, timestamp):
        if event_type == '入':
            if len(self.parking_lot) < self.capacity:
                # 车辆进入停车场
                position = len(self.parking_lot) + 1
                self.parking_lot.append(car_id)
                self.car_info[car_id] = (timestamp, 'Parking Lot', position)
                return f'车{car_id}停在{position}车位'
            else:
                # 停车场满了,车辆进入便道
                position = len(self.lane) + 1
                self.lane.append(car_id)
                self.car_info[car_id] = (timestamp, 'Lane', position)
                return f'车{car_id}停在便道{position}.'
        elif event_type == '出':
            if car_id in self.car_info:
                arrival_time, location_type, position = self.car_info[car_id]
                if location_type == 'Parking Lot':
                    # 车辆从停车场离开
                    self.parking_lot.remove(car_id)
                    duration = (timestamp - arrival_time).seconds // 60  # 转换为分钟
                    fee = duration * 0.1  # 假设每分钟收费0.1元
                    del self.car_info[car_id]
                    return f'车{car_id}离开停车场,共停{duration}分钟后. 花费:{fee:.2f}元'
                elif location_type == 'Lane':
                    # 车辆从便道离开
                    self.lane.remove(car_id)
                    del self.car_info[car_id]
                    return f'车{car_id}已经离开便道.'
            else:
                return "未找到该车辆"
         else:
              return "车辆进出未知,请重新输入"

2.3.1 process_event参数定义:

  • self:指向ParkingLotSystem类实例本身的引用。
  • event_type:事件类型,可以是"入"(车辆进入)或者"出"(车辆离开)。
  • car_id:车辆的唯一标识符,即车牌号。
  • timestamp:事件发生的时间戳。

2.3.2 如果事件为"入"(if event_type == "入"):

首先检查停车场是否还有空位。这里通过比较停车场当前的车辆数量和停车场容量来实现。

如果停车场有空位,车辆就会进入停车场。这里做了几件事:

  1. 计算车辆停放的位置(position),它是当前停车场车辆数量加1。
  2. 将车牌号添加到停车场列表(self.parking_lot)中。
  3. 在车辆信息字典(self.car_info)中为该车辆创建一个条目,包含到达时间、位置类型及其位置。
  4. 返回一个字符串,说明车辆已经停在指定的车位上。

如果停车场已满,车辆就会进入便道。这里也做了几件事:

  1. 计算车辆在便道上的位置(position)。
  2. 将车牌号添加到便道列表(self.lane)里。
  3. 在车辆信息字典(self.car_info)中为该车创建一个条目,同样包含到达时间、位置类型及其位置。
  4. 返回一个字符串,说明车辆停在指定的便道位置处。

2.3.3 如果事件为"出"(if event_type == "出"):

首先检查车牌号(car_id)是否存在于self.car_info字典中。

如果不在:则返回一个字符串,说明未找到该车辆。

如果存在并且该车停在停车场

  1. 从self.parking_lot列表中移除该车辆ID。
  2. 计算车辆停留的时间。将当前时间减去车辆的到达时间,并且将结果转换为分钟。
  3. 根据停留时间计算停车费用。这里假设每分钟收费0.1元。
  4. 从self.car_info字典中删除该车的信息,
  5. 返回一个字符串,说明车辆已经离开停车场,并提供了停留时间和花费的费用。

如果存在并且该车停在便道

  1. 从self.lane列表中移除该车牌号。
  2. 从self.car_info字典中删除该车辆信息。
  3. 返回一个字符串,说明车辆已经离开便道。

2.3.4 如果事件非入非出:

即用户输入非法,返回一个字符串,提醒用户正确输入。

3 界面设计

def main():
    layout = [
        [sg.Text('出入:'), sg.InputText(key='-EVENT-')],
        [sg.Text('车牌号:'), sg.InputText(key='-CARID-')],
        [sg.Text('时间( 形式: YYYY-MM-DD HH:MM):'), sg.InputText(key='-TIMESTAMP-')],
        [sg.Button('提交'), sg.Button('退出')],
        [sg.Text('输出:', key='-OUTPUT-')],
        [sg.Text('泊车状况:', key='-STATUS-')],
    ]

    window = sg.Window('停车场管理系统', layout)

    parking_lot_system = ParkingLotSystem(5) # 假设停车场容量为5辆车

    while True:
        event, values = window.read()
        if event == sg.WIN_CLOSED or event == '退出':
            break
        if event == '提交':
            event_type = values['-EVENT-']
            car_id = values['-CARID-']
            timestamp_str = values['-TIMESTAMP-']
            try:
                timestamp = datetime.strptime(timestamp_str, '%Y-%m-%d %H:%M')
            except ValueError:
                window['-OUTPUT-'].update('请按照要求输入时间')
                continue

            output = parking_lot_system.process_event(event_type, car_id, timestamp)
            window['-OUTPUT-'].update(output)
            window['-STATUS-'].update(
                f'停车状况: {parking_lot_system.parking_lot}\n便道: {list(parking_lot_system.lane)}')

    window.close()


if __name__ == '__main__':
    main()

3.1 创建窗口布局

  • 使用sg库的元素定义了一个窗口布局,包括文本输入框、按钮和文本显示区域。
  • 文本显示区(sg.Text)以及文本输入区(sg.InputText)存在键(key),以便在程序运行时引用和更新这些元素。

3.2 事件循环

  • 使用while True循环来处理用户输入和更新界面。
  • window.read()读取用户输入的事件和值。
  • 如果用户关闭窗口或点击退出按钮,则退出循环。
  • 如果用户点击提交按钮,则尝试处理提交的事件,以下介绍具体处理:
    1. 从界面获取事件类型、车牌号和时间。
    2. 尝试将时间字符串转换为datetime对象。如果失败,则提醒用户按格式输入
    3. 调用parking-lot-system.process-event方法处理事件,并更新界面上的信息
  • 退出循环后,关闭窗口

4 结果展示

以下展示部分运行结果

PySimpleGUI制作简易停车场管理系统_第1张图片

PySimpleGUI制作简易停车场管理系统_第2张图片

5源码

import PySimpleGUI as sg
from datetime import datetime
from collections import deque


class ParkingLotSystem:
    def __init__(self, capacity):
        self.capacity = capacity
        self.parking_lot = []  # 使用列表作为来模拟停车场
        self.lane = deque()  # 使用deque作为队列来模拟便道
        self.car_info = {}  # 存储车辆信息的字典,键为车牌号码,值为(到达时间,停车位置)元组

    def process_event(self, event_type, car_id, timestamp):
        if event_type == '入':
            if len(self.parking_lot) < self.capacity:  # 检查停车场是否还有空位
                # 车辆进入停车场
                position = len(self.parking_lot) + 1  # 计算位置
                self.parking_lot.append(car_id)  # 将该车添加到停车场列表,即停在停车场之中。
                self.car_info[car_id] = (timestamp, 'Parking Lot', position)  # 为该车创建一个条目,其中包含到达时间、位置等信息
                return f'车{car_id}停在{position}车位'
            else:
                # 停车场满了,车辆进入便道
                position = len(self.lane) + 1
                self.lane.append(car_id)
                self.car_info[car_id] = (timestamp, 'Lane', position)
                return f'车{car_id}停在便道{position}.'
        elif event_type == '出':
            if car_id in self.car_info:
                arrival_time, location_type, position = self.car_info[car_id]
                if location_type == 'Parking Lot':
                    # 车辆从停车场离开
                    self.parking_lot.remove(car_id)  # 在停车区里移除
                    duration = (timestamp - arrival_time).seconds // 60  # 转换为分钟
                    fee = duration * 0.1  # 假设每分钟收费0.1元
                    del self.car_info[car_id]  # 删除车牌号
                    return f'车{car_id}离开停车场,共停{duration}分钟后. 花费:{fee:.2f}元'
                elif location_type == 'Lane':
                    # 车辆从便道离开
                    self.lane.remove(car_id)
                    del self.car_info[car_id]
                    return f'车{car_id}已经离开便道.'
            else:
                return "未找到该车辆"
        else:
            return "车辆进出未知,请重新输入"


def main():
    layout = [
        [sg.Text('出入:'), sg.InputText(key='-EVENT-')],
        [sg.Text('车牌号:'), sg.InputText(key='-CARID-')],
        [sg.Text('时间( 形式: YYYY-MM-DD HH:MM):'), sg.InputText(key='-TIMESTAMP-')],
        [sg.Button('提交'), sg.Button('退出')],
        [sg.Text('输出:', key='-OUTPUT-')],
        [sg.Text('泊车状况:', key='-STATUS-')],
    ]

    window = sg.Window('停车场管理系统', layout)  # 创建窗口

    parking_lot_system = ParkingLotSystem(5)  # 假设停车场容量为5辆汽车

    while True:
        event, values = window.read()
        if event == sg.WIN_CLOSED or event == '退出':
            break
        if event == '提交':
            # 获取出入情况、车牌号、时间
            event_type = values['-EVENT-']
            car_id = values['-CARID-']
            timestamp_str = values['-TIMESTAMP-']
            try:
                timestamp = datetime.strptime(timestamp_str, '%Y-%m-%d %H:%M')
            except ValueError:
                window['-OUTPUT-'].update('请按照要求输入时间')  # datetime对象转化失败,则提醒用户按格式输入
                continue

            # 输入目前停车场的泊车状况
            output = parking_lot_system.process_event(event_type, car_id, timestamp)
            window['-OUTPUT-'].update(output)
            window['-STATUS-'].update(f'停车状况: {parking_lot_system.parking_lot}\n便道: {list(parking_lot_system.lane)}')

    window.close()


if __name__ == '__main__':
    main()

文章到此结束,感谢各位阅读,祝您生活愉快!

你可能感兴趣的:(python,开发语言)