123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937 |
- import ctypes
- import inspect
- import os
- import signal
- import sys
- sys.path.append('..')
- import datetime
- import json
- import threading
- import time
- import traceback
- from functools import partial
- import requests
- from PyQt5.QtCore import QSize, QDateTime
- from PyQt5.QtCore import pyqtSignal, QTimer, Qt
- from PyQt5.QtGui import QFont, QIcon, QPixmap, QCursor, QColor
- from PyQt5.QtWidgets import QMessageBox, QListWidgetItem, QMainWindow, QMenu, QPushButton, QGridLayout, QListWidget, \
- QLabel, QHeaderView, QTableWidgetItem, QAbstractItemView, QSizePolicy, QApplication
- import google.protobuf.text_format as tf
- import ui.spaceUi as sui
- from window_controller.pickup_passwd_window import PickupWindow, ResultReturn
- import message.message_pb2 as message
- from window_controller.reparking_window import ReparkingWindow
- from window_controller.full_car_window import FullcarWindow
- from window_controller.led import Led
- import copy
- import async_communication as cmt
- import mytool.db_helper.db_operation as spmng
- class MainWindow(QMainWindow, sui.Ui_MainWindow):
- # # 取车界面信号
- # signal_dict = pyqtSignal(dict)
- def __init__(self, parking_config, mq_config, db_config, parent=None):
- super(MainWindow, self).__init__(parent)
- self.command_dict = {}
- self.unit_space_dict = None
- self.setupUi(self)
- # 数据存储
- self.btn_positions = [(i, j) for i in range(parking_config['row'], -1, -1) for j in
- range(parking_config['column'])]
- self._dispatch_statu = {}
- self.unit_space_is_init = False
- self.process_is_init = False
- self.unit_list = {'A1': 11, 'A2': 12, 'A3': 13, 'A4': 14, 'B1': 21, 'B2': 22, 'B3': 23, 'B4': 24, 'B5': 25,
- 'C1': 31, 'C2': 32,
- 'A': [11, 12, 13, 14], 'B': [21, 22, 23, 24, 25], 'C': [31, 32], '所有': None}
- self.label_dict = {}
- self.list_widget_dict = {}
- self.setWindowTitle(parking_config['window_title'])
- # 锁
- self.data_lock = threading.Lock()
- # 配置导入初始化数据库和rabbitmq
- self.parking_config = parking_config
- self.db = spmng.DBOperation(db_config['db_ip'], db_config['db_port'], db_config['db_name'],
- db_config['db_user'], db_config['db_password'])
- self.rabbitmq = cmt.RabbitAsyncCommunicator(mq_config['mq_ip'], mq_config['mq_port'], mq_config['mq_user'],
- mq_config['mq_password'])
- try:
- self.rabbitmq.Init(None, mq_config['mq_statu_exchange_keys'])
- for ex, key in mq_config['mq_statu_exchange_keys']:
- self.rabbitmq.bind_statu_callback(ex, key, self.receive_dispatch_statu)
- self.rabbitmq.start()
- except Exception as e:
- print('rabbitmq启动失败!' + str(e.args))
- self.out_date = None
- self.in_date = None
- # 记录表单元号,流程表单元号,车位表单元号
- self.record_unit = self.db_comboBox.currentText()
- self.process_unit = self.process_comboBox.currentText()
- self.parking_unit = self.unit_comboBox.currentText()
- # 调度状态指示灯
- self.plc_statu_led = Led()
- self.plc_statu_led.setEnabled(False) # 设置为不使能状态,如果需要切换可以设置为True。则可以实现点击切换指示灯颜色的效果
- self.plc_statu_led.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
- self.plc_statu_led.setChecked(False) # 设置状态
- self.dispatch_heart_timer = cmt.TimeStatu(1, 0.1)
- self.horizontalLayout_11.addWidget(self.plc_statu_led)
- self.db_statu_led = Led()
- self.db_statu_led.setEnabled(False) # 设置为不使能状态,如果需要切换可以设置为True。则可以实现点击切换指示灯颜色的效果
- self.db_statu_led.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
- self.db_statu_led.setChecked(False) # 设置状态
- self.horizontalLayout_11.addWidget(self.db_statu_led)
- # 是否输入过密码 密码保护默认五分钟
- self.t_time = time.time()
- self.is_pwd = False
- # 数据历史记录默认设置
- self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
- self.tableWidget.itemClicked.connect(self.show_car_image)
- self.tableWidget.setHorizontalHeaderLabels(parking_config['record_title'])
- now = datetime.datetime.now()
- zero_today = now - datetime.timedelta(hours=now.hour, minutes=now.minute, seconds=now.second,
- microseconds=now.microsecond)
- last_today = zero_today + datetime.timedelta(hours=23, minutes=59, seconds=59)
- self.in_dateTimeEdit.setDateTime(zero_today)
- self.out_dateTimeEdit.setDateTime(last_today)
- self.in_dateTimeEdit_2.setDateTime(zero_today)
- self.out_dateTimeEdit_2.setDateTime(last_today)
- self.db_find_Button.clicked.connect(self.db_record_find)
- # 车位显示模式
- self.show_model = self.car_number_rbtn_2.isChecked()
- # 切换库位按钮关联函数
- self.find_btn.clicked.connect(self.find_btn_click)
- self.update_unit_btn.clicked.connect(self.update_btn_click)
- self.update_unit_btn_2.clicked.connect(self.update_process_unit_btn_click)
- # 车位管理显示的相关配置
- self.unit = parking_config["unit"]
- if self.unit == 11 or self.unit == 25 or self.unit == 32:
- self.in_occupy_space = 2
- self.out_occupy_space = 2
- else:
- self.in_occupy_space = 3
- self.out_occupy_space = 3
- self.controlroom_occupy_space = 0
- key = list(self.unit_list.keys())[list(self.unit_list.values()).index(self.unit)]
- self.unit_comboBox.setCurrentText(key)
- # 初始化显示库位高度
- font = QFont()
- font.setFamily('宋体')
- font.setBold(False)
- font.setPointSize(15)
- self.parking_listWidget.setFont(font)
- self.pushButton_grade1.setIcon(QIcon(QPixmap("./images/grade1.png")))
- self.pushButton_grade2.setIcon(QIcon(QPixmap("./images/grade2.png")))
- self.pushButton_grade3.setIcon(QIcon(QPixmap("./images/grade3.png")))
- self.pushButton_grade1.setText("限高:" + str(parking_config['grade1']))
- self.pushButton_grade2.setText("限高:" + str(parking_config['grade2']))
- self.pushButton_grade3.setText("限高:" + str(parking_config['grade3']))
- # 数据缓存
- self.space_dict = {}
- self.record_all_unit_park_dict = {}
- self.record_all_unit_pick_dict = {}
- self.record_unit_park_dict = {}
- self.record_unit_pick_dict = {}
- self.record_total_unit_park_dict = {11:{},12:{},13:{},14:{},21:{},22:{},23:{},24:{},25:{},31:{},32:{}}
- self.record_total_unit_pick_dict = {11:{},12:{},13:{},14:{},21:{},22:{},23:{},24:{},25:{},31:{},32:{}}
- self.last_command_dict = {}
- # 数据库更新时间
- self.db_update_time = time.time() - 3
- self.db_connect_statu = False
- # 数据库查询线程
- self.db_query = threading.Thread(target=self.db_query)
- self.db_query_isClose = False
- self.db_query.start()
- # 启动界面刷新定时器
- self.timer = QTimer()
- self.timer.timeout.connect(self.Switch)
- self.timer.start(200)
- def receive_dispatch_statu(self, statu, ex, key):
- # 调度状态接收
- self._dispatch_statu[key] = statu
- def db_query(self):
- while self.db_query_isClose is False:
- # 查询车位
- self.data_lock.acquire()
- self.space_dict = self.db.query_space_in_unit(self.unit)
- # 查询指令表
- for unit in self.unit_list[self.process_unit]:
- self.last_command_dict[unit] = self.db.query_command_all_in_unit_and_sort(unit)
- # 当前选中时间段内所有单元记录表数据
- self.record_all_unit_park_dict = self.db.query_park_count_in_time(self.in_date, self.out_date)
- self.record_all_unit_pick_dict = self.db.query_pick_count_out_time(self.in_date, self.out_date)
- # 当前选中时间内指定单元记录数据
- if len(self.record_unit) != 1 and self.unit_list[self.record_unit] is not None:
- self.record_unit_park_dict = self.db.query_park_count_in_time_and_unit(self.in_date, self.out_date,
- self.unit_list[self.record_unit])
- self.record_unit_pick_dict = self.db.query_pick_count_out_time_and_unit(self.in_date, self.out_date,
- self.unit_list[
- self.record_unit])
- # 当前选中时间内指定总单元记录数据
- if len(self.record_unit) == 1:
- for unit in self.unit_list[self.record_unit]:
- self.record_total_unit_park_dict[unit] = self.db.query_park_count_in_time_and_unit(self.in_date,
- self.out_date,
- unit)
- self.record_total_unit_pick_dict[unit] = self.db.query_pick_count_out_time_and_unit(self.in_date,
- self.out_date,
- unit)
- self.data_lock.release()
- # 数据库更新时间
- self.db_update_time = time.time()
- time.sleep(0.1)
- # 界面刷新定时器
- def Switch(self):
- # 200毫秒刷新一次,同时检查密码定时器是否超过五分钟
- time_now = time.time()
- if self.is_pwd is True and time_now - self.t_time > 300:
- self.is_pwd = False
- self.t_time = time_now
- self.in_date = self.in_dateTimeEdit_2.dateTime().toPyDateTime().strftime("%Y-%m-%d %H:%M:%S")
- self.out_date = self.out_dateTimeEdit_2.dateTime().toPyDateTime().strftime("%Y-%m-%d %H:%M:%S")
- # 更新记录表单元号,流程表单元号,车位表单元号
- self.record_unit = self.db_comboBox.currentText()
- # 检查连接
- self.db_connect_statu = self.check_connect_statu()
- if self.db_connect_statu:
- # self.data_lock.acquire()
- # 车位管理
- self.parkspace_show(self.unit, self.in_occupy_space, self.out_occupy_space)
- # # 流程监控
- self.process_monitoring(self.process_unit)
- # # 停车数量记录
- self.show_parkingData()
- # self.data_lock.release()
- # 检查数据库连接
- def check_connect_statu(self):
- # 检查调度连接
- key = "dispatch_%d_statu_port" % self.unit
- if (key in self._dispatch_statu) is False or self._dispatch_statu[key].timeout():
- self.plc_statu_led.setChecked(False)
- else:
- statu = self._dispatch_statu[key].statu
- dispatch_node_statu = message.dispatch_node_statu()
- try:
- tf.Parse(statu, dispatch_node_statu)
- except Exception:
- pass
- if self.dispatch_heart_timer.statu != dispatch_node_statu.plc_heartbeat:
- self.dispatch_heart_timer = cmt.TimeStatu(dispatch_node_statu.plc_heartbeat)
- self.plc_statu_led.setChecked(True)
- if self.dispatch_heart_timer.timeout():
- self.plc_statu_led.setChecked(False)
- # 检查数据库连接
- if time.time() - self.db_update_time > 3:
- self.db_statu_led.setChecked(False)
- else:
- self.db_statu_led.setChecked(True)
- return self.db_statu_led.isChecked()
- # 车位显示
- def parkspace_show(self, unit, in_occupy_space, out_occupy_space):
- if unit == 1:
- self.unit_label.setText("A")
- elif unit == 2:
- self.unit_label.setText("B")
- elif unit == 11:
- self.unit_label.setText("A-1")
- elif unit == 12:
- self.unit_label.setText("A-2")
- elif unit == 13:
- self.unit_label.setText("A-3")
- elif unit == 14:
- self.unit_label.setText("A-4")
- elif unit == 21:
- self.unit_label.setText("B-1")
- elif unit == 22:
- self.unit_label.setText("B-2")
- elif unit == 23:
- self.unit_label.setText("B-3")
- elif unit == 24:
- self.unit_label.setText("B-4")
- elif unit == 25:
- self.unit_label.setText("B-5")
- elif unit == 31:
- self.unit_label.setText("C-1")
- elif unit == 32:
- self.unit_label.setText("C-2")
- if unit == 31 or unit == 32:
- self.pushButton_grade1.setIcon(QIcon(QPixmap("./images/grade1.png")))
- self.pushButton_grade2.setIcon(QIcon(QPixmap("./images/grade1.png")))
- self.pushButton_grade3.setIcon(QIcon(QPixmap("./images/grade3.png")))
- self.pushButton_grade1.setText("限高:" + str(self.parking_config['grade4']))
- self.pushButton_grade2.setText("限高:" + str(self.parking_config['grade4']))
- self.pushButton_grade3.setText("限高:" + str(self.parking_config['grade3']))
- else:
- self.pushButton_grade1.setIcon(QIcon(QPixmap("./images/grade1.png")))
- self.pushButton_grade2.setIcon(QIcon(QPixmap("./images/grade2.png")))
- self.pushButton_grade3.setIcon(QIcon(QPixmap("./images/grade3.png")))
- self.pushButton_grade1.setText("限高:" + str(self.parking_config['grade1']))
- self.pushButton_grade2.setText("限高:" + str(self.parking_config['grade2']))
- self.pushButton_grade3.setText("限高:" + str(self.parking_config['grade3']))
- # 绘制车位按钮
- if self.space_dict is None:
- return
- space_dict = copy.deepcopy(self.space_dict)
- is_show_car_number = self.car_number_rbtn_2.isChecked()
- if self.unit_space_dict != space_dict:
- print('有修改')
- if self.unit_space_is_init == False:
- self.unit_space_dict = copy.deepcopy(space_dict)
- self.unit_space_is_init = True
- is_drawIn = False
- is_drawOut = False
- is_drawControlRoom = False
- for park, position in zip(space_dict, self.btn_positions):
- btn = QPushButton()
- font, text_str, stylesheet, tool_tip = self.get_btn_show(park)
- btn.setFont(font)
- btn.setLayout(QGridLayout())
- btn.setText(text_str)
- btn.setStyleSheet(stylesheet)
- btn.setToolTip(tool_tip)
- btn.setObjectName(str(park["table_id"]))
- if text_str == "入 口" and is_drawIn is False:
- self.unit_gridLayout.addWidget(btn, *position, 1, in_occupy_space)
- is_drawIn = True
- elif text_str == "出 口" and is_drawOut is False:
- self.unit_gridLayout.addWidget(btn, *position, 1, out_occupy_space)
- is_drawOut = True
- elif text_str == " 控制室 " and is_drawControlRoom is False:
- self.unit_gridLayout.addWidget(btn, *position, 1,
- self.parking_config['controlroom_occupy_space'])
- is_drawControlRoom = True
- elif text_str != "出 口" and text_str != "入 口" and text_str != " 控制室 ":
- btn.setContextMenuPolicy(Qt.CustomContextMenu)
- btn.customContextMenuRequested.connect(self.park_btn_right_click)
- btn.clicked.connect(self.park_btn_left_click)
- self.unit_gridLayout.addWidget(btn, *position)
- else:
- for park1, park2 in zip(self.unit_space_dict, space_dict):
- if park1 != park2:
- font, text_str, stylesheet, tool_tip = self.get_btn_show(park2)
- results = self.findChild(QPushButton, str(park2["table_id"]))
- if results is None :
- return
- results.setFont(font)
- results.setText(text_str)
- results.setStyleSheet(stylesheet)
- results.setToolTip(tool_tip)
- self.unit_space_dict = copy.deepcopy(space_dict)
- if self.show_model != is_show_car_number:
- self.show_model = is_show_car_number
- for park in self.unit_space_dict:
- if park["statu"] == 2:
- font, text_str, stylesheet, tool_tip = self.get_btn_show(park)
- results = self.findChild(QPushButton, str(park["table_id"]))
- results.setFont(font)
- results.setText(text_str)
- results.setStyleSheet(stylesheet)
- results.setToolTip(tool_tip)
- # 流程监控
- def process_monitoring(self, unit_char):
- if self.process_is_init is False:
- for i in self.unit_list[unit_char]:
- self.list_widget_dict[i] = QListWidget(self)
- self.list_widget_dict[i].setContextMenuPolicy(Qt.CustomContextMenu)
- self.list_widget_dict[i].customContextMenuRequested.connect(self.custom_right_menu)
- self.list_widget_dict[i].setStyleSheet("border:5px solid #014F84;")
- self.list_widget_dict[i].setObjectName(('list_widget_%d' % (i + 1)))
- self.process_horizontalLayout.addWidget(self.list_widget_dict[i])
- self.label_dict[i] = QLabel(self)
- self.label_dict[i].setText(unit_char + "-" + str((i % 10)))
- self.label_dict[i].setAlignment(Qt.AlignCenter)
- self.label_dict[i].setFont(QFont("华文楷体", 60, QFont.Bold))
- self.command_dict[i] = []
- self.unit_horizontalLayout.addWidget(self.label_dict[i])
- self.process_is_init = True
- for i in self.unit_list[unit_char]:
- if (i in self.last_command_dict.keys()) is False or self.last_command_dict[i] is None:
- return
- else:
- last_command_dict = copy.deepcopy(self.last_command_dict[i])
- if self.command_dict[i] != last_command_dict:
- self.command_dict[i] = copy.deepcopy(last_command_dict)
- self.list_widget_dict[i].clear()
- for dict in self.command_dict[i]:
- if dict['statu'] != 3:
- self.list_widget_dict[i].addItem(self.get_listWidget_item(dict))
- for dict in self.command_dict[i]:
- if dict['statu'] == 3:
- self.list_widget_dict[i].addItem(self.get_listWidget_item(dict))
- # 刷新停车数据
- def show_parkingData(self):
- # 有一个数据是空就直接返回
- if self.record_all_unit_park_dict is None or self.record_all_unit_pick_dict is None or self.record_unit_park_dict is None or \
- self.record_unit_pick_dict is None or self.record_total_unit_park_dict is None or self.record_total_unit_pick_dict is None:
- return
- record_all_unit_park_dict,record_all_unit_pick_dict,record_unit_park_dict,record_unit_pick_dict,record_total_unit_park_dict,record_total_unit_pick_dict = \
- copy.deepcopy(self.record_all_unit_park_dict),copy.deepcopy(self.record_all_unit_pick_dict),copy.deepcopy(self.record_unit_park_dict),copy.deepcopy(self.record_unit_pick_dict),copy.deepcopy(self.record_total_unit_park_dict),copy.deepcopy(self.record_total_unit_pick_dict)
- unit_park_count = unit_pick_count = 0
- all_park_count, all_pick_count = len(record_all_unit_park_dict), len(record_all_unit_pick_dict)
- # 当前选中时间内指定总单元记录数据
- if len(self.record_unit) == 1:
- for unit in self.unit_list[self.record_unit]:
- unit_park_count = unit_park_count + len(record_total_unit_park_dict[unit])
- unit_pick_count = unit_pick_count + len(record_total_unit_pick_dict[unit])
- # 当前选中时间内指定单元记录数据
- elif len(self.record_unit) != 1 and self.unit_list[self.record_unit] is not None:
- unit_park_count, unit_pick_count = len(record_unit_park_dict), len(record_unit_pick_dict)
- else:
- unit_park_count, unit_pick_count = all_park_count, all_pick_count
- self.unit_park_count_label.setText("该单元停车{value}次".format(value=unit_park_count))
- self.unit_pick_count_label.setText("该单元取车{value}次".format(value=unit_pick_count))
- self.all_park_count_label.setText("所有库停车{value}次".format(value=all_park_count))
- self.all_pick_count_label.setText("所有库取车{value}次".format(value=all_pick_count))
- def show_parking_details(self, park_dict):
- self.parking_listWidget.clear()
- for poit in park_dict.items():
- item = QListWidgetItem()
- item.setSizeHint(QSize(50, 39))
- name = self.get_name(poit[0])
- if name == '未知':
- continue
- value = poit[1]
- if name == '楼层':
- value = value - self.parking_config['floor_minus']
- item.setText(name + ":" + str(value))
- self.parking_listWidget.addItem(item)
- res = self.db.query_space_in_car_number(park_dict['car_number'])
- self.plate_full_image_label.setPixmap(QPixmap(""))
- self.plate_clip_image_label.setPixmap(QPixmap(""))
- if len(res) > 0:
- try:
- rep = requests.get(res[0]['plate_full_image'])
- pix = QPixmap()
- pix.loadFromData(rep.content)
- pix = pix.scaled(self.plate_full_image_label.size(), Qt.KeepAspectRatio)
- self.plate_full_image_label.setPixmap(pix)
- except Exception as e:
- print('全景图:' + str(e.args))
- try:
- rep = requests.get(res[0]['plate_clip_image'])
- pix = QPixmap()
- pix.loadFromData(rep.content)
- pix = pix.scaled(self.plate_clip_image_label.size(), Qt.KeepAspectRatio)
- self.plate_clip_image_label.setPixmap(pix)
- except Exception as e:
- print('特写图:' + str(e.args))
- def find_btn_click(self):
- text = self.find_lineEdit.text()
- if text == '':
- QMessageBox.question(None, "提示", "请输入要查询的内容",
- QMessageBox.Ok)
- return
- if self.car_number_rbtn.isChecked():
- park_dict = self.db.query_space_in_car_number(text)
- if len(park_dict) > 0:
- self.show_parking_details(park_dict[0])
- else:
- QMessageBox.question(None, "查询结果", "车牌号:" + text + " 未查询到数据!",
- QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
- elif self.key_rbtn.isChecked():
- park_dict = self.db.query_space_in_primary_key(text)
- if len(park_dict) > 0:
- self.show_parking_details(park_dict[0])
- else:
- QMessageBox.question(None, "查询结果", "唯一码:" + text + " 未查询到数据!",
- QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
- # elif self.parking_rbtn.isChecked():
- # park_dict = self.db.query_space_in_unit_and_table_id(self.unit, text)
- # if len(park_dict) > 0:
- # self.show_parking_details(park_dict[0])
- #
- # else:
- # QMessageBox.question(None, "查询结果", "车位id:" + text + " 未查询到数据!",
- # QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
- return
- def update_process_unit_btn_click(self):
- self.process_unit = self.process_comboBox.currentText()
- for i in range(self.process_horizontalLayout.count()):
- self.process_horizontalLayout.itemAt(i).widget().deleteLater()
- for i in range(self.unit_horizontalLayout.count()):
- self.unit_horizontalLayout.itemAt(i).widget().deleteLater()
- self.process_is_init = False
- def update_btn_click(self):
- self.parking_unit = self.unit_comboBox.currentText()
- if self.unit == self.unit_list[self.parking_unit]:
- return
- self.unit = self.unit_list[self.parking_unit]
- if self.unit == 11 or self.unit == 25 or self.unit == 32:
- self.in_occupy_space = 2
- self.out_occupy_space = 2
- else:
- self.in_occupy_space = 3
- self.out_occupy_space = 3
- for i in range(self.unit_gridLayout.count()):
- self.unit_gridLayout.itemAt(i).widget().deleteLater()
- self.unit_space_is_init = False
- def park_btn_left_click(self):
- if self.db_connect_statu:
- sender = self.sender()
- tool_tip = sender.toolTip()
- dict = json.loads(tool_tip)
- self.show_parking_details(dict)
- else:
- QMessageBox.critical(None, "提示", "数据库连接断开!", QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
- def park_btn_right_click(self):
- if self.db_connect_statu:
- menu = QMenu(self)
- sender = self.sender()
- tool_tip = sender.toolTip()
- dict = json.loads(tool_tip)
- action = menu.addAction('启用车位')
- action.triggered.connect(partial(self.btn_opeSpace, dict, 0))
- action = menu.addAction('停用车位')
- action.triggered.connect(partial(self.btn_disableSpace, dict, 10))
- action = menu.addAction('清除车位')
- action.triggered.connect(partial(self.btn_clearSpace, dict))
- action = menu.addAction('正常取车')
- action.triggered.connect(partial(self.btn_pickUp, dict, message.PROCESS_NORMAL))
- action = menu.addAction('强制取车')
- action.triggered.connect(partial(self.btn_pickUp, dict, message.PROCESS_ONLY_TO_DISPATCH))
- action = menu.addAction('虚拟取车')
- action.triggered.connect(partial(self.btn_pickUp, dict, message.PROCESS_ONLY_TO_PAY))
- # action = menu.addAction('更换车位')
- # action.triggered.connect(partial(self.btn_replace_parking, dict))
- action = menu.addAction('填充车位')
- action.triggered.connect(partial(self.btn_fill_parking, dict))
- action = menu.addAction('增加备注')
- action.triggered.connect(partial(self.btn_add_remarks, dict))
- menu.exec_(QCursor.pos())
- else:
- QMessageBox.critical(None, "提示", "数据库连接断开!", QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
- def btn_disableSpace(self, dict, statu):
- if self.is_input_pwd() is True:
- res = self.db.update_space_status_in_space_id(dict["id"], statu)
- if res == 0:
- QMessageBox.question(None, '提示', '更新车位失败!请检查是否点击错误!',
- QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
- def btn_opeSpace(self, dict, statu):
- if self.is_input_pwd() is True:
- res = self.db.update_space_status_in_space_id(dict["id"], statu)
- if res == 0:
- QMessageBox.question(None, '提示', '更新车位失败!请检查是否点击错误!',
- QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
- def btn_clearSpace(self, dict):
- if self.is_input_pwd() is True:
- res = self.db.clear_space_data(dict["id"])
- if res == 0:
- QMessageBox.question(None, '提示', '更新车位失败!请检查是否点击错误!',
- QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
- def btn_pickUp(self, dict, table_process_mod):
- if self.is_input_pwd() is True:
- table = message.pick_table()
- # table.statu = message.table_statu()
- table.statu.table_process_mod = table_process_mod
- a = dict['primary_key']
- table.primary_key = dict["primary_key"]
- self.rabbitmq.publish("command_ex", "user_pick_command_request_port",
- tf.MessageToString(table, as_utf8=True))
- QMessageBox.question(None, '提示', '取车消息发送成功!',
- QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
- # def btn_replace_parking(self, dict):
- # if self.is_input_pwd() is True:
- # if dict['car_number'] == 'None' or dict['primary_key'] == 'None':
- # QMessageBox.question(None, '提示', '没有车牌号或唯一码,不符合更换车位条件!',
- # QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
- # return
- # repwind = ReparkingWindow()
- # repwind.exec()
- # res = repwind.get_results()
- # if res is True:
- # target_parking = self.db.query_parking_in_unit_tableid(dict['unit'], repwind.get_park_tableid())[0]
- # if target_parking['car_number'] is not None:
- # QMessageBox.question(None, '提示', '目标车位不为空!',
- # QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
- # return
- # parking = self.db.query_space_in_car_number(dict['car_number'])[0]
- #
- # space_info_sql = "NULL"
- # measure_info_sql = "NULL"
- # plate_color_sql = "NULL"
- # plate_type_sql = "NULL"
- # plate_confidence_sql = "NULL"
- # recognition_time_sql = "NULL"
- # plate_full_image_sql = "NULL"
- # plate_clip_image_sql = "NULL"
- #
- # if parking['space_info'] is not None:
- # space_info_sql = "'%s'" % parking['space_info']
- #
- # if parking['measure_info'] is not None:
- # measure_info_sql = "'%s'" % parking['measure_info']
- #
- # if parking['plate_color'] is not None:
- # plate_color_sql = "'%s'" % parking['plate_color']
- #
- # if parking['plate_type'] is not None:
- # plate_type_sql = "'%s'" % parking['plate_type']
- #
- # if parking['plate_confidence'] is not None:
- # plate_confidence_sql = "%d" % parking['plate_confidence']
- #
- # if parking['recognition_time'] is not None:
- # recognition_time_sql = "'%s'" % parking['recognition_time']
- #
- # if parking['plate_full_image'] is not None:
- # plate_full_image_sql = "'%s'" % parking['plate_full_image']
- #
- # if parking['plate_clip_image'] is not None:
- # plate_clip_image_sql = "'%s'" % parking['plate_clip_image']
- #
- # sql2 = "update space set car_number='%s', primary_key='%s', statu=%d , space_info=%s , measure_info=%s ,\
- # plate_color=%s , plate_type=%s , plate_confidence=%s , recognition_time=%s , plate_full_image=%s , plate_clip_image=%s where id=%d" \
- # % (parking['car_number'], parking['primary_key'], parking['statu'], space_info_sql,
- # measure_info_sql,
- # plate_color_sql, \
- # plate_type_sql, plate_confidence_sql, recognition_time_sql, plate_full_image_sql,
- # plate_clip_image_sql, target_parking['id'])
- # # print(sql2)
- #
- # res = self.db.update(sql2)
- # if res == 0:
- # QMessageBox.question(None, '提示', '执行失败!',
- # QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
- # return
- # res = self.db.clear_space_data(parking['id'])
- # if res > 0:
- # QMessageBox.question(None, '提示', '车位交换成功!',
- # QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
- def btn_fill_parking(self, dict):
- if self.is_input_pwd() is True:
- fullcar = FullcarWindow()
- fullcar.exec()
- if fullcar.get_results() is True:
- car_number = fullcar.get_text()
- res = self.db.update_space_status_car_number_in_space_id(dict['id'], car_number, 2)
- if res > 0:
- QMessageBox.question(None, '提示', '车位填充成功!',
- QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
- def btn_add_remarks(self, dict):
- if self.is_input_pwd() is True:
- fullcar = FullcarWindow()
- fullcar.exec()
- if fullcar.get_results() is True:
- remark = fullcar.get_text()
- res = self.db.update_space_remark_in_space_id(dict['id'],remark)
- if res > 0:
- QMessageBox.question(None, '提示', '车位添加备注成功!',
- QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
- def get_btn_show(self, park):
- font = QFont()
- font.setFamily('宋体')
- font.setPointSize(21)
- if park["statu"] == 6:
- text_str = "入 口"
- font.setBold(True)
- elif park["statu"] == 7:
- text_str = "出 口"
- font.setBold(True)
- elif park["statu"] == 8:
- text_str = " 控制室 "
- font.setBold(True)
- # elif park["statu"] == 10 and park["remark"] is not None:
- # text_str = park["remark"][0:4]
- # font.setPointSize(20)
- elif (park["statu"] == 2 or park["statu"] == 1) and park[
- "car_number"] is not None and self.car_number_rbtn_2.isChecked():
- text_str = park["car_number"]
- font.setPointSize(20)
- else:
- text_str = "车位:%d\n楼层:%d" % (park["table_id"], (park["floor"] - self.parking_config['floor_minus']))
- font.setPointSize(10)
- background_color = ""
- background_image = ""
- if park["statu"] == 10:
- background_color = "background-color:rgb(255,130,130);"
- elif park["statu"] == 2:
- background_color = "background-color:rgb(248,239,71);"
- elif park["statu"] == 1:
- background_color = "background-color:rgb(240,120,30);"
- elif park["statu"] == 6 or park["statu"] == 7 or park["statu"] == 8:
- background_color = "background-color:rgb(0,162,232);"
- # elif park["statu"] == 0 and park["remark"] is not None:
- # background_color = "background-color:rgb(255,130,130);"
- elif park["statu"] == 0:
- background_color = "background-color:rgb(195,195,195);"
- # 设置背景图
- if park["height"] == self.parking_config['grade1']:
- background_image = "background-image: url(./images/grade1.png);"
- elif park["height"] == self.parking_config['grade2']:
- background_image = "background-image: url(./images/grade2.png);"
- elif park["height"] == self.parking_config['grade3']:
- background_image = "background-image: url(./images/grade3.png);"
- elif park["height"] == self.parking_config['grade4']:
- background_image = "background-image: url(./images/grade1.png);"
- stylesheet = background_color + "pressed{padding-top:2px;padding-left:2px;};" + background_image + "background-repeat:no-repeat;"
- for key in park.keys():
- if park[key] is None:
- park[key] = ''
- tool_tip = json.dumps(park)
- return font, text_str, stylesheet, tool_tip
- # 显示车辆图片
- def show_car_image(self, Item):
- try:
- row = Item.row() # 获取行数
- col = self.tableWidget.columnCount() # 获取列数 注意是column而不是col哦
- plate_full_image = self.tableWidget.item(row, col - 2)
- plate_clip_image = self.tableWidget.item(row, col - 1)
- self.plate_full_image_label_2.setPixmap(QPixmap(""))
- self.plate_clip_image_label_2.setPixmap(QPixmap(""))
- if plate_full_image is not None:
- rep = requests.get(plate_full_image.text())
- pix = QPixmap()
- pix.loadFromData(rep.content)
- pix = pix.scaled(self.plate_full_image_label_2.size(), Qt.KeepAspectRatio)
- self.plate_full_image_label_2.setPixmap(pix)
- if plate_clip_image is not None:
- rep = requests.get(plate_clip_image.text())
- pix = QPixmap()
- pix.loadFromData(rep.content)
- pix = pix.scaled(self.plate_clip_image_label_2.size(), Qt.KeepAspectRatio)
- self.plate_clip_image_label_2.setPixmap(pix)
- except Exception as e:
- traceback.print_exc()
- # 查询历史记录
- def db_record_find(self):
- if self.db_connect_statu is False:
- QMessageBox.critical(None, "提示", "数据库连接断开!", QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
- return
- if self.unit_list[self.record_unit] == None:
- unit_sql = ""
- elif type(self.unit_list[self.record_unit]) != int:
- unit_sql = "and ("
- for i in self.unit_list[self.record_unit]:
- unit_sql = unit_sql + "unit_id=%d or " % i
- unit_sql = unit_sql[:-3] + ")"
- else:
- unit_sql = "and (unit_id = %s)" % self.unit_list[self.record_unit]
- in_datatime = self.in_dateTimeEdit.dateTime().toPyDateTime()
- out_datatime = self.out_dateTimeEdit.dateTime().toPyDateTime()
- car_number = self.car_number_lineEdit.text()
- in_time_sql = "(in_time_start >= '%s' and in_time_start <= '%s') " % (in_datatime, out_datatime)
- out_time_sql = "(out_time_start >= '%s' and out_time_start <= '%s') " % (in_datatime, out_datatime)
- in_and_out_time_sql = "(" + in_time_sql + " or " + out_time_sql + ")"
- if self.park_radioButton.isChecked():
- time_sql = in_time_sql
- elif self.pick_radioButton.isChecked():
- time_sql = out_time_sql
- else:
- time_sql = in_and_out_time_sql
- car_number_sql = ""
- if car_number != "":
- car_number_sql = "and car_number like '%{}%'".format(car_number)
- sql = "select * from record where %s %s %s " % (time_sql, unit_sql, car_number_sql)
- print(sql)
- results = self.db.query(sql)
- self.tableWidget.clearContents()
- self.tableWidget.setRowCount(0)
- for i in range(len(results)):
- row_count = self.tableWidget.rowCount() # 返回当前行数(尾部)
- self.tableWidget.insertRow(row_count) # 尾部插入一行
- for j, value in zip(range(0, len(results[i])), results[i].values()):
- self.tableWidget.setItem(i, j, QTableWidgetItem(str(value)))
- # print(results)
- def custom_right_menu(self, pos):
- sender = self.sender()
- menu = QMenu()
- opt1 = menu.addAction("恢复排队")
- opt2 = menu.addAction("设为故障")
- opt3 = menu.addAction("删除任务")
- try:
- hitIndex = sender.indexAt(pos).row()
- # print(hitIndex)
- if hitIndex > -1:
- # 获取item内容
- car_number = sender.item(hitIndex).toolTip()
- action = menu.exec_(sender.mapToGlobal(pos))
- if self.is_input_pwd() is True:
- if action == opt1:
- res = self.db.update_command_status_in_car_number(car_number, 0)
- if action == opt2:
- res = self.db.update_command_status_in_car_number(car_number, 3)
- if action == opt3:
- self.is_pwd = False
- if self.is_input_pwd('该操作存在风险,请再次输入密码!') is True:
- res = self.db.delete_command(car_number)
- if res > 0:
- QMessageBox.question(None, '提示', '指令修改成功!',
- QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
- except Exception as e:
- pass
- def is_input_pwd(self, tipstr=None):
- if self.is_pwd is False:
- # 组装显示信息
- # 实例取车窗口,并以模态窗口形式显示
- pickup_window = PickupWindow(tipstr)
- pickup_window.exec_()
- res = pickup_window.getResult()
- if res is ResultReturn.OK:
- self.is_pwd = True
- self.t_time = time.time()
- return True
- else:
- return False
- return True
- def get_listWidget_item(self, dict):
- item = QListWidgetItem()
- item.setFont(QFont('微软雅黑', 15, QFont.Bold))
- item.setToolTip(dict['car_number'])
- show_str = ""
- if dict['type'] == 1: # 存车指令
- item.setBackground(QColor(185, 240, 240))
- if (dict['statu'] == 0): # 排队
- item.setForeground(QColor(80, 80, 80))
- show_str = dict['car_number'] + " 排队中,请稍等片刻"
- elif (dict['statu'] == 1): # 工作
- item.setForeground(QColor('blue'))
- show_str = dict['car_number'] + " 存车中,等待存车结束"
- elif (dict['statu'] == 2): # 已完成
- item.setForeground(QColor('green'))
- show_str = dict['car_number'] + " 存车已完成"
- elif (dict['statu'] == 3): # 已完成
- item.setForeground(QColor('red'))
- show_str = dict['car_number'] + " 故障,请联系管理员!"
- show_str = "存 " + show_str
- elif dict['type'] == 2: # 取车指令
- item.setBackground(QColor(250, 240, 200))
- if (dict['statu'] == 0): # 排队
- item.setForeground(QColor(80, 80, 80))
- show_str = dict['car_number'] + " 排队中,请稍等片刻"
- elif (dict['statu'] == 1): # 工作
- item.setForeground(QColor('blue'))
- show_str = dict['car_number'] + " 取车中,等待取车结束"
- elif (dict['statu'] == 2): # 已完成
- item.setForeground(QColor('green'))
- show_str = dict['car_number'] + " 已完成,请到 %d 号出口取车" % (dict["export_id"])
- elif (dict['statu'] == 3): # 已完成
- item.setForeground(QColor('red'))
- show_str = dict['car_number'] + " 故障,请联系管理员!"
- show_str = "取 " + show_str
- item.setText(show_str)
- return item
- def closeEvent(self, event):
- results = QMessageBox.question(self, '退出', '你确定要退出吗?', QMessageBox.Yes | QMessageBox.No,
- QMessageBox.No) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
- if results == QMessageBox.Yes:
- self.db_query_isClose = True
- self.db_query.join()
- self.rabbitmq.close()
- event.accept() # 接受关闭事件
- # 强制结束进程
- pid = os.getpid()
- os.kill(pid, signal.SIGTERM)
- else:
- event.ignore() # 忽略关闭事件
- def get_name(self, key):
- if key == 'id':
- return '总车位号'
- elif key == 'table_id':
- return '表编号'
- elif key == 'floor':
- return '楼层'
- elif key == 'height_level':
- return '限高等级'
- elif key == 'height':
- return '限高'
- elif key == 'wheel_base_level':
- return '限制轴距等级'
- elif key == 'wheel_base':
- return '限制轴距'
- elif key == 'car_number':
- return '车牌号'
- elif key == 'statu':
- return '车位状态'
- elif key == 'plate_color':
- return '号牌颜色'
- elif key == 'plate_type':
- return '号牌类型'
- elif key == 'plate_confidence':
- return '号牌可信度'
- elif key == 'recognition_time':
- return '识别时间'
- elif key == 'primary_key':
- return '唯一码'
- elif key == 'plate_full_image':
- return '号牌全景图'
- elif key == 'plate_clip_image':
- return '号牌特写图'
- elif key == 'remark':
- return '备注'
- else:
- return '未知'
|