import base64 import datetime import sys from itertools import product import requests import message.message_pb2 as message from PyQt5.QtWidgets import QApplication, QSizePolicy, QLabel, QWidget, QListWidgetItem, QGridLayout import json import threading import time from functools import partial from PyQt5.QtCore import pyqtSignal, Qt, QTimer, QThread, QSize from PyQt5.QtGui import QCursor, QFont, QColor, QPixmap, QIcon, QImage from PyQt5.QtWidgets import QPushButton, QMainWindow, QMenu, QMessageBox import message.message_pb2 as message import google.protobuf.text_format as tf import re import ui.spaceUi as sui import db_helper.db_operation as spmng from config import MQ_CONFIG as mq_config import async_communication as cmt from config import PARKING_CONFIG as park_config class MainWindow(QMainWindow, sui.Ui_MainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setupUi(self) font = QFont() font.setFamily('宋体') font.setBold(False) font.setPointSize(17) self.parking_listWidget.setFont(font) self.pushButton_1480.setIcon(QIcon(QPixmap("./images/1480.png"))) self.pushButton_1500.setIcon(QIcon(QPixmap("./images/1500.png"))) self.pushButton_2050.setIcon(QIcon(QPixmap("./images/2050.png"))) if park_config.unit == 11: self.unit_label.setText("A-1") elif park_config.unit == 12: self.unit_label.setText("A-2") elif park_config.unit == 13: self.unit_label.setText("A-3") elif park_config.unit == 14: self.unit_label.setText("A-4") elif park_config.unit == 21: self.unit_label.setText("B-1") elif park_config.unit == 22: self.unit_label.setText("B-2") elif park_config.unit == 23: self.unit_label.setText("B-3") elif park_config.unit == 24: self.unit_label.setText("B-4") elif park_config.unit == 25: self.unit_label.setText("B-5") elif park_config.unit == 31: self.unit_label.setText("C-1") elif park_config.unit == 32: self.unit_label.setText("C-2") self.btn_positions = [(i, j) for i in range(14, -1, -1) for j in range(6)] self.space_dict = {} self.space_is_init = False self.show_model = self.car_number_rbtn_2.isChecked() self.rmq_statu_dict = {} self.command_dict = {} self.timer = QTimer() self.timer.timeout.connect(self.Switch) self.timer.start(200) self.find_btn.clicked.connect(self.find_btn_click) def getBackGroundColor(self, color): if color == "red": return "background-color:rgb(255,70,70)" elif color == "gray": return "background-color:rgb(168,168,168)" elif color == "green": return "background-color:rgb(0,180,0)" elif color == "yellow": return "background-color:rgb(248,239,71)" elif color == "pastel": return "background-color:rgb(241,158,194)" def get_name(self,key): if key == 'id': return '下标' elif key == 'table_id': return '表编号' elif key == 'floor': return '楼层' elif key == 'height': 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 '唯一码' else: return '未知' def show_parking_details(self,park_dict): self.parking_listWidget.clear() for poit in park_dict.items(): item = QListWidgetItem() item.setSizeHint(QSize(50, 42)) name = self.get_name(poit[0]) if name == '未知': continue value = poit[1] if name == '楼层': value = value - 2 item.setText(name + ":" + str(value)) self.parking_listWidget.addItem(item) res = g_space.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 = g_space.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 = g_space.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 = g_space.query_space_in_unit_and_table_id(park_config.unit,text) if len(park_dict) > 0: self.show_parking_details(park_dict[0]) else: QMessageBox.question(None, "查询结果", "车位id:" + text + " 未查询到数据!", QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容 return def park_btn_left_click(self): sender = self.sender() tool_tip = sender.toolTip() dict = json.loads(tool_tip) self.show_parking_details(dict) def park_btn_right_click(self): 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)) menu.exec_(QCursor.pos()) def btn_disableSpace(self, dict, statu): res = g_space.update_space_status(dict["id"], statu) if res == 0: QMessageBox.question(None, '提示', '更新车位失败!请检查是否点击错误!', QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容 def btn_opeSpace(self, dict, statu): res = g_space.update_space_status(dict["id"], statu) if res == 0: QMessageBox.question(None, '提示', '更新车位失败!请检查是否点击错误!', QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容 def btn_clearSpace(self, dict): res = g_space.clear_space_data(dict["id"]) if res == 0: QMessageBox.question(None, '提示', '更新车位失败!请检查是否点击错误!', QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容 def btn_pickUp(self, dict): table = message.pick_table() table.primary_key = dict["primary_key"] g_rabbitmq.publish(mq_config.mq_command_exchange_name, "user_pick_command_request_port", tf.MessageToString(table, as_utf8=True)) QMessageBox.question(None, '提示', '取车消息发送成功!', QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容 def get_btn_show(self, park): font = QFont() font.setFamily('宋体') font.setPointSize(21) if park["serial_id"] in park_config.channel_ex[park_config.unit]["入口"]: text_str = "入 口" font.setBold(True) elif park["serial_id"] in park_config.channel_ex[park_config.unit]["出口"]: text_str = "出 口" font.setBold(True) elif park["statu"] == 2 and park["car_number"] is not None and self.car_number_rbtn_2.isChecked(): text_str = " "+park["car_number"] font.setPointSize(17) else: text_str = " 车位:%d\n 楼层:%d" % (park["table_id"], park["floor"] - 2) font.setPointSize(10) stylesheet = "" if park["statu"] == 10: stylesheet = "background-color:rgb(255,130,130);pressed{padding-top:2px;padding-left:2px;};text-align:left;" elif park["statu"] == 2 and park["car_number"] is not None: stylesheet = "background-color:rgb(248,239,71);pressed{padding-top:2px;padding-left:2px;};text-align:left;" elif park["statu"] == 6 or park["statu"] == 7: stylesheet = "background-color:rgb(0,162,232);pressed{padding-top:2px;padding-left:2px;};" elif park["statu"] == 0: stylesheet = "background-color:rgb(195,195,195);pressed{padding-top:2px;padding-left:2px;};text-align:left;" icon = QIcon() # 设置按钮图标 if park["height"] == 1.48: icon = QIcon(QPixmap('./images/1480.png')) # 设置按钮图标 elif park["height"] == 1.50: icon = QIcon(QPixmap('./images/1500.png')) # 设置按钮图标 elif park["height"] == 2.05: icon = QIcon(QPixmap('./images/2050.png')) # 设置按钮图标 tool_tip = '{"id":%d,\n"table_id":%d,\n"floor":%d, \n"height":%f,\n"car_number":"%s" , \n"statu":%d,\n"plate_color":"%s" ,\n"plate_type":"%s" ,\n"plate_confidence":"%s",\n"recognition_time":"%s",\n"primary_key":"%s"}' % ( park["id"], (-1 if park["table_id"] is None else park["table_id"]), park["floor"], (0 if park["height"] is None else park["height"]), park["car_number"],park["statu"],park["plate_color"], park["plate_type"],park["plate_confidence"],park["recognition_time"],park["primary_key"]) return font, text_str, stylesheet, tool_tip, icon def Switch(self): # 绘制车位按钮 space_dict = g_space.query_space_in_unit(park_config.unit) if len(space_dict) < 0: return is_show_car_number = self.car_number_rbtn_2.isChecked() if self.space_dict != space_dict: if self.space_is_init == False: self.space_dict = space_dict self.space_is_init = True is_drawIn = False is_drawOut = False for park, position in zip(self.space_dict, self.btn_positions): btn = QPushButton() font, text_str, stylesheet, tool_tip, icon = 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"])) btn.setIcon(icon) btn.setIconSize(QSize(30,30)) if text_str == "入 口" and is_drawIn is False: self.unit_gridLayout.addWidget(btn, *position, 1, len(park_config.channel_ex[park_config.unit]["入口"])) is_drawIn = True elif text_str == "出 口" and is_drawOut is False: self.unit_gridLayout.addWidget(btn, *position, 1, len(park_config.channel_ex[park_config.unit]["出口"])) is_drawOut = True elif 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.space_dict, space_dict): if park1 != park2: font, text_str, stylesheet, tool_tip,icon = self.get_btn_show(park2) results = self.findChild(QPushButton, str(park2["table_id"])) results.setFont(font) results.setText(text_str) results.setStyleSheet(stylesheet) results.setToolTip(tool_tip) self.space_dict = space_dict if self.show_model != is_show_car_number: self.show_model = is_show_car_number for park in self.space_dict: if park["statu"] == 2: font, text_str, stylesheet, tool_tip,icon = 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 closeEvent(self, event): results = QMessageBox.question(self, '退出', '你确定要退出吗?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容 if results == QMessageBox.Yes: g_rabbitmq.close() event.accept() # 接受关闭事件 else: event.ignore() # 忽略关闭事件 if __name__ == '__main__': g_rabbitmq = cmt.RabbitAsyncCommunicator(mq_config.mq_ip, mq_config.mq_port, mq_config.mq_user, mq_config.mq_password) g_rabbitmq.Init(None, None) g_rabbitmq.start() g_space = spmng.DBOperation() app = QApplication(sys.argv) mainWindow = MainWindow() mainWindow.showMaximized() mainWindow.plate_full_image_label.setMaximumSize(mainWindow.plate_full_image_label.size()) mainWindow.plate_clip_image_label.setMaximumSize(mainWindow.plate_clip_image_label.size()) sys.exit(app.exec_())