IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 传感器数据模拟软件【StreamFaker】【带界面】【发送到Rabbitmq】【python3+pyqt5实现】 -> 正文阅读

[大数据]传感器数据模拟软件【StreamFaker】【带界面】【发送到Rabbitmq】【python3+pyqt5实现】

Background

  • 大家都知道哈,我做的基本都是传感器监测类项目,很多项目开发时传感器都没安装呢,所以没有数据。但是,项目在开发中,没有数据的话,数据处理逻辑和接口很难开发,即使写出来了没数据测试也是不放心的哈。
  • 所以,就有了这个软件,模拟假数据(另一篇博客中也提到过【传感器监测数据实时存储、计算和展示(RabbitMQ-Flink-InfluxDB)】哈,那个版本还是没有UI的,还有很多bug的)。
  • 那,【StreamFaker】【提取码:king】这是最终版的带UI操作界面,界面比较丑哈,我这里只注重功能性哈,以后有机会再美化吧。
  • 说实话,数据模拟还是挺麻烦的。下面我简单介绍下软件的基本信息和使用方法。

1、先上软件最终效果哈

有些功能没有实现哈,这里说下能用的话,其他的也不怎么用的到,所以后来没在整了。
第一行菜单栏

  • StreamFaker:软件名,自己起的,这个名字我用了,你们不许用咯;
  • dev:测试环境(支持不同的开发环境);
  • cr11g_landslip:项目名简写(不同的项目使用时修改下配置就行了);

第二行

  • 项目管理和设置这两个按钮没用哈,在配置里(configures.xls)直接修改;

第三行

  • 项目管理和设置这两个按钮没用哈,在配置里(configures.xls)直接修改;
  • 启动/停止和退出可以使用的;

第四行传感器选择

  • 就是个摆设,复选框也没用哈,在配置里(configures.xls)直接修改;

第五行运行状态

  • 这个可以用哈,运行时就是黄灯,停止时就是灰色的灯;

最后一行

  • 是否推送MQ:摆设哈;
  • 是否打开日志:可以用哈,发送的数据会存储在日志文件中(StreamFaker.log);

在这里插入图片描述

2、传感器信息

我们项目中的传感器,不同的类型有不同的指标,如下图所示,有的指标是传感器的监测数据,有的是后面计算出来的

在这里插入图片描述

3、配置文件 configures.xls

我们需要配置rabbitmq(第一个sheet)、项目(第二个sheet)和传感器信息(第三个sheet)。

  • isEnable:使用哪个环境,对应界面上第一行的dev;
  • appNameSuffix:项目名简写,对应界面上第一行的cr11g_landslip;

其他都是rabbitmq的基本配置信息了。

在这里插入图片描述

第二个sheet,key代表的依次为,是否启用,项目id,传感器类型,指标个数,最大值,最小值,数据间隔(即发送的数据频率);

在这里插入图片描述

第三个sheet,是每个类型下的传感器id。

在这里插入图片描述

4、源码

需要 imgs目录和configures.xls配置文件

在这里插入图片描述

import datetime
import logging
import os
import random
import sys
import threading
import time
from logging import handlers

import pika
import xlrd
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QComboBox, QPushButton, QSpinBox

# 软件名称
from pika import BasicProperties

self_name = 'StreamFaker'
# 停止标志
stop_flag = False
# 是否生成日志标志
log_flag = True


# 日志级别关系映射
class Logger(object):
    level_relations = {
        'debug': logging.DEBUG,
        'info': logging.INFO,
        'warning': logging.WARNING,
        'error': logging.ERROR,
        'critical': logging.CRITICAL
    }

    def __init__(self, filename, level='info', when='D', backCount=3, fmt='%(asctime)s - %(levelname)s: %(message)s'):
        self.logger = logging.getLogger(filename)
        format_str = logging.Formatter(fmt)  # 设置日志格式
        self.logger.setLevel(self.level_relations.get(level))  # 设置日志级别
        sh = logging.StreamHandler()  # 往屏幕上输出
        sh.setFormatter(format_str)  # 设置屏幕上显示的格式
        th = handlers.TimedRotatingFileHandler(filename=filename, when=when, backupCount=backCount,
                                               encoding='utf-8')  # 往文件里写入#指定间隔时间自动生成文件的处理器
        # 实例化TimedRotatingFileHandler
        # interval是时间间隔,backupCount是备份文件的个数,如果超过这个个数,就会自动删除,when是间隔的时间单位,单位有以下几种:
        # S 秒
        # M 分
        # H 小时、
        # D 天、
        # W 每星期(interval==0时代表星期一)
        # midnight 每天凌晨
        th.setFormatter(format_str)  # 设置文件里写入的格式
        self.logger.addHandler(sh)  # 把对象加到logger里
        self.logger.addHandler(th)


# 日志文件名
log = Logger(self_name + '.log')


class Configure:
    # 读取配置文件
    rd = xlrd.open_workbook('configures.xls')

    # 获取 rabbitmq 的配置信息 sheet
    rabbitmq_sheet = rd.sheet_by_name('rabbitmq')
    # 获取传感器的基本信息
    baseInfo_sheet = rd.sheet_by_name('baseInfo')
    # 获取传感器类型和通讯标号信息
    serialNumber_sheet = rd.sheet_by_name('serialNumber')

    # 获取传感器的基本配置信息
    def get_sensor_conf(self):
        """
        列表元素为字典结构:
        conf_sensor = {
            'projectId': '27',
            'targetType': '21',
            'serialNumbers': [1, 3, 5],
            'quotaAmount': 5,
            'minValue': 1,
            'maxValue': 10,
            'interval': 100
            }
        """
        # 最终返回列表,列表元素为字典结构
        list_conf = []
        # 获取总列数
        cols = self.baseInfo_sheet.ncols
        # 以第一列为字典的 key
        dict_keys = self.baseInfo_sheet.col_values(0)
        # 遍历所有列,其中列的 isEnable 为 1 的列作为字典的 value
        for col_index in range(1, cols):
            # 判断每列的第二行的数据是否 为 1
            col = self.baseInfo_sheet.col_values(col_index)
            if int(col[1]) == 1:
                dict_values = col
                # 放入字典结构中
                conf_sensor = {}
                organize_dict(conf_sensor, dict_keys, dict_values)
                list_conf.append(conf_sensor)
        # 获取唯一id, targetType 和 serialNumbers 的对应关系
        sc_dict = self.get_serial_number()
        # 根据 pid、targetType 和 serialNumbers 的对应关系放入字段结构中
        for conf in list_conf:
            key = conf['key']
            tt = conf['targetType']
            conf_key = key + '_' + tt
            conf['serialNumbers'] = sc_dict[conf_key]
        for cfg in list_conf:
            cfg.pop('key')
            cfg.pop('isEnable')
        return list_conf

    # 获取各项目的传感器类型和通讯编号信息
    def get_serial_number(self):
        # 最终返回字典结构 key: pid_tt    value: [sc]
        sc_dict = {}
        # 获取总列数
        cols = self.serialNumber_sheet.ncols
        # 遍历所有列
        for col_index in range(0, cols):
            # 每列的第一个值为唯一id,第二个值为类型,其它值为 sc
            pid = self.serialNumber_sheet.col_values(col_index)[0]
            tt = self.serialNumber_sheet.col_values(col_index)[1]
            sc = self.serialNumber_sheet.col_values(col_index)[2:]
            # 把空值去掉
            sc = list(filter(None, sc))
            # 把数值转成 int
            sc = [int(v) for v in sc]
            # 字典结构的 key
            dict_key = str(pid) + '_' + str(int(tt))
            # 放入字典结构
            sc_dict[dict_key] = sc
        # 返回数据
        return sc_dict

    # 获取 rabbitmq 的配置信息
    def get_rabbitmq_conf(self):
        """
        最终返回字典结构:
        conf_rabbitmq = {
            'env': 'dev',
            'host': 'elephant',
            'port': 5672,
            'vHost': 'panda',
            'username': 'panda',
            'password': 'Rabbit1234!',
            'exchange': 'dky_cft',
            'routingKey': 'payload'
            }
        """
        # 最终返回字典结构
        conf_rabbitmq = {}
        # 获取总列数
        cols = self.rabbitmq_sheet.ncols
        # 以第一列为字典的 key
        dict_keys = self.rabbitmq_sheet.col_values(0)[2:]
        # 遍历所有列,其它列的 isEnable 为 1 的列作为字典的 value
        for col_index in range(1, cols):
            # 判断每列的第二行的数据是否 为 1
            col = self.rabbitmq_sheet.col_values(col_index)
            if int(col[1]) == 1:
                env = col[0]
                conf_rabbitmq['env'] = env
                dict_values = col[2:]
                organize_dict(conf_rabbitmq, dict_keys, dict_values)
        return conf_rabbitmq


# 组织字典结构数据
def organize_dict(conf_dict, dict_keys, dict_values):
    # 数值为 int 的 key
    int_keys = ['port', 'projectId', 'targetType', 'quotaAmount', 'interval']
    str_keys = ['projectId', 'targetType']
    for index in range(0, len(dict_keys)):
        dict_key = dict_keys[index]
        dict_value = dict_values[index]
        if dict_key in int_keys:
            dict_value = int(dict_value)
        if dict_key in str_keys:
            dict_value = str(dict_value)
        conf_dict[dict_key] = dict_value


class RabbitMQUtil(object):
    """
    构造方法:
    config = {
        'host': '192.168.18.155',
        'port': 5672,
        'vHost': 'panda',
        'username': 'panda',
        'password': 'Rabbit1234!',
        'exchange': 'sensorPayload_test',
        'routingKey': 'payload'
        }
    """

    # 初始化配置
    def __init__(self, conf):
        super().__init__()
        self.host = conf['host']
        self.port = conf['port']
        self.vHost = conf['vHost']
        self.username = conf['username']
        self.password = conf['password']
        self.exchange = conf['exchange']
        self.routingKey = conf['routingKey']
        self.credential = None
        self.connection = None
        self.channel = None

        try:
            self.credential = pika.PlainCredentials(self.username, self.password)
            self.connection = pika.BlockingConnection(
                pika.ConnectionParameters(self.host, self.port, self.vHost, self.credential))
            self.channel = self.connection.channel()
        except():
            print("connect error, please check the config")

    # 发布消息
    def public_msg(self, json):
        # body = json.dumps({"test": "test"})
        self.channel.basic_publish(
            exchange=self.exchange,
            routing_key=self.routingKey,
            body=json
            # properties=BasicProperties.FLAG_DELIVERY_MODE
        )

    # 接收处理消息的回调函数
    def callback(self, body):
        super()
        print(str(body).replace('b', '').replace('\'', ''))

    # 订阅消息
    def consume_msg(self, queue):
        self.channel.queue_declare(queue=queue, durable=True, arguments={"x-message-ttl": 259200000})
        self.channel.basic_consume(queue, self.callback, True)
        self.channel.start_consuming()

    # 关闭连接
    def close(self):
        if not self.connection:
            self.connection.close()
        else:
            print("connection already disconnected")


class MsgUtil(object):
    """
    构造方法:
    config = {
        'projectId': '23',
        'targetType': '1',
        'serialNumbers': [1,5,6,7],
        'targetAmount': 4,
        'quotaAmount': 6,
        'minValue': 1,
        'maxValue': 10
        }
    """

    def __init__(self, conf):
        self.projectId = conf['projectId']
        self.targetType = conf['targetType']
        self.serialNumbers = conf['serialNumbers']
        self.quotaAmount = conf['quotaAmount']
        self.minValue = conf['minValue']
        self.maxValue = conf['maxValue']
        self.funCode = '1'
        self.reserve = '1'
        self.targetAmount = None
        self.timestamp = None

    # 获取逗号分隔的字符串(项目id,时间(17位字符串),功能码,测点类型,预留字节,测定个数,指标个数,测点1id,指标1数值,指标2数值,...,测点2id,指标1数值,指标2数值,...,)
    # 例子:100,20201015170020100,1,14,1,2,3,1,-7.182,-6.868,2.397,23,-9.077,5.666,-6.547
    def get_msg(self):
        self.targetAmount = len(self.serialNumbers)
        self.timestamp = get_format_time()
        base_info_seq = (self.projectId, str(self.timestamp), self.funCode, self.targetType, self.reserve,
                         str(self.targetAmount), str(self.quotaAmount))
        val_seq = ()
        for serialCode in self.serialNumbers:
            val_seq = val_seq + (str(serialCode),)
            for i in range(1, self.quotaAmount + 1):
                random_value = get_random_value(self.minValue, self.maxValue)
                val_seq = val_seq + (random_value,)

        return get_comma_str(base_info_seq, val_seq)


# 自定义线程类,指定频率向 RabbitMQ 发送消息
class MyThread(threading.Thread):
    conn = None

    def __init__(self, thread_id, interval, msg_util):
        threading.Thread.__init__(self)
        self.thread_id = thread_id
        self.interval = interval * 1000 * 1000
        self.msg_util = msg_util
        self.__running = threading.Event()  # 用于停止线程的标识
        self.__running.set()  # 将running设置为True
        self.conn = get_rabbit_connection()
        self._stop_event = threading.Event()

    def run(self):
        lastTime = 0
        while self.__running.isSet():
            message = self.msg_util.get_msg()
            thisTime = get_nano_now()
            diffTime = thisTime - lastTime
            if diffTime < self.interval:
                # 休眠
                delay = (self.interval - diffTime) / (1000 * 1000 * 1000)
                # print("===============< 休眠 >=================", delay)
                time.sleep(delay)
            # 判断是否已停止
            if stop_flag:
                return
            # 发布消息
            if log_flag:
                log.logger.info(message)
            # print(message)
            self.conn.public_msg(message)
            lastTime = get_nano_now()

    def stop(self):
        self.__running.clear()  # 设置为False
        self._stop_event.set()


# 获取获逗号分隔的字符串,参数是元素为字符串的 tuple
def get_comma_str(*params):
    comma = ','
    res = ()
    for p in params:
        res = res + p
    return comma.join(res)


# 获取获取指定范围的一个随机数(字符串类型),保留三位小数
def get_random_value(minValue, maxValue):
    return str(round(random.uniform(minValue, maxValue), 5))


# 获取当前时间,格式:20200929173338500
def get_format_time():
    now = datetime.datetime.now()
    return now.strftime("%Y%m%d%H%M%S%f")[:-3]


# 获取13位当前毫秒时间戳,格式:1602747077320
def get_nano_now():
    return time.time_ns()


# 获取 RabbitMQ 连接
def get_rabbit_connection():
    config = Configure()
    return RabbitMQUtil(config.get_rabbitmq_conf())


# 获取启动后 app 的名字
def get_app_name():
    config = Configure()
    env = config.get_rabbitmq_conf()["env"]
    app_name_suffix = config.get_rabbitmq_conf()["appNameSuffix"]
    if app_name_suffix is None or app_name_suffix == "":
        app_name_suffix = get_current_os_dir()
    return self_name + "【" + env + "】" + "【" + app_name_suffix + "】"


# 获取当前系统目录名
def get_current_os_dir():
    dirs = os.path.split(os.path.realpath(__file__))[0].split("\\")
    return dirs[len(dirs) - 1]


# UI 界面
class Ui_mainWindow(object):

    def setupUi(self, mainWindow):
        mainWindow.setObjectName("mainWindow")
        mainWindow.resize(799, 571)
        mainWindow.setMouseTracking(True)
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("imgs/wlf.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        mainWindow.setWindowIcon(icon)
        mainWindow.setAutoFillBackground(False)
        mainWindow.setStyleSheet("background-color: rgb(218, 238, 237);")

        # mainWindow【主窗口】
        self.centralwidget = QtWidgets.QWidget(mainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.frame = QtWidgets.QFrame(self.centralwidget)
        self.frame.setGeometry(QtCore.QRect(0, 50, 801, 81))
        self.frame.setStyleSheet("background-color: rgb(158, 178, 209);")
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")

        # QPushButton【项目管理】
        self.pushButton = QtWidgets.QPushButton(self.frame)
        self.pushButton.setGeometry(QtCore.QRect(120, 20, 91, 41))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setBold(True)
        font.setWeight(75)
        self.pushButton.setFont(font)
        self.pushButton.setStyleSheet("background-color: rgb(90, 181, 134);")
        icon1 = QtGui.QIcon()
        icon1.addPixmap(QtGui.QPixmap("imgs/home-filling.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.pushButton.setIcon(icon1)
        self.pushButton.setIconSize(QtCore.QSize(25, 25))
        self.pushButton.setObjectName("pushButton")

        # QPushButton【设置】
        self.pushButton_2 = QtWidgets.QPushButton(self.frame)
        self.pushButton_2.setGeometry(QtCore.QRect(280, 20, 91, 41))
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_2.setFont(font)
        self.pushButton_2.setStyleSheet("background-color: rgb(90, 181, 134);")
        icon2 = QtGui.QIcon()
        icon2.addPixmap(QtGui.QPixmap("imgs/setting-filling.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.pushButton_2.setIcon(icon2)
        self.pushButton_2.setIconSize(QtCore.QSize(25, 25))
        self.pushButton_2.setObjectName("pushButton_2")

        # QPushButton【开始】
        self.pushButton_3 = QtWidgets.QPushButton(self.frame)
        self.pushButton_3.setGeometry(QtCore.QRect(430, 20, 91, 41))
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_3.setFont(font)
        self.pushButton_3.setStyleSheet("background-color: rgb(90, 181, 134);")
        icon3 = QtGui.QIcon()
        icon3.addPixmap(QtGui.QPixmap("imgs/play-fill.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.pushButton_3.setIcon(icon3)
        self.pushButton_3.setIconSize(QtCore.QSize(30, 30))
        self.pushButton_3.setCheckable(False)
        self.pushButton_3.setChecked(False)
        self.pushButton_3.setDefault(False)
        self.pushButton_3.setObjectName("pushButton_3")

        # QPushButton【停止】
        self.pushButton_4 = QtWidgets.QPushButton(self.frame)
        self.pushButton_4.setGeometry(QtCore.QRect(430, 20, 91, 41))
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_4.setFont(font)
        self.pushButton_4.setStyleSheet("background-color: rgb(90, 181, 134);")
        icon4 = QtGui.QIcon()
        icon4.addPixmap(QtGui.QPixmap("imgs/suspended-fill.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.pushButton_4.setIcon(icon4)
        self.pushButton_4.setIconSize(QtCore.QSize(30, 30))
        self.pushButton_4.setCheckable(False)
        self.pushButton_4.setChecked(False)
        self.pushButton_4.setObjectName("pushButton_4")

        # QPushButton【退出】
        self.pushButton_5 = QtWidgets.QPushButton(self.frame)
        self.pushButton_5.setGeometry(QtCore.QRect(580, 20, 91, 41))
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_5.setFont(font)
        self.pushButton_5.setStyleSheet("background-color: rgb(90, 181, 134);")
        icon5 = QtGui.QIcon()
        icon5.addPixmap(QtGui.QPixmap("imgs/exit1.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.pushButton_5.setIcon(icon5)
        self.pushButton_5.setIconSize(QtCore.QSize(21, 21))
        self.pushButton_5.setObjectName("pushButton_5")

        # QPushButton【设置】
        self.pushButton_7 = QtWidgets.QPushButton(self.frame)
        self.pushButton_7.setGeometry(QtCore.QRect(280, 20, 91, 41))
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_7.setFont(font)
        self.pushButton_7.setStyleSheet("background-color: rgb(227, 0, 0);")
        self.pushButton_7.setIcon(icon2)
        self.pushButton_7.setIconSize(QtCore.QSize(25, 25))
        self.pushButton_7.setObjectName("pushButton_7")
        self.pushButton_4.raise_()
        self.pushButton_3.raise_()
        self.pushButton_7.raise_()
        self.pushButton.raise_()
        self.pushButton_2.raise_()
        self.pushButton_5.raise_()

        # QPushButton【启用传感器展示】
        self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox.setGeometry(QtCore.QRect(100, 170, 591, 101))
        font = QtGui.QFont()
        font.setBold(False)
        font.setWeight(50)
        self.groupBox.setFont(font)
        self.groupBox.setStyleSheet("background-color: rgb(114, 230, 171);")
        self.groupBox.setObjectName("groupBox")
        self.checkBox = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox.setGeometry(QtCore.QRect(20, 40, 71, 16))
        self.checkBox.setObjectName("checkBox")
        self.checkBox_2 = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox_2.setGeometry(QtCore.QRect(80, 40, 71, 16))
        self.checkBox_2.setObjectName("checkBox_2")
        self.groupBox_2 = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox_2.setGeometry(QtCore.QRect(100, 310, 221, 111))
        self.groupBox_2.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.groupBox_2.setStyleSheet("background-color: rgb(114, 230, 171);")
        self.groupBox_2.setObjectName("groupBox_2")

        # QPushButton【运行状态】
        self.pushButton_6 = QtWidgets.QPushButton(self.groupBox_2)
        self.pushButton_6.setGeometry(QtCore.QRect(50, 20, 121, 81))
        self.pushButton_6.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.pushButton_6.setText("")
        icon6 = QtGui.QIcon()
        icon6.addPixmap(QtGui.QPixmap("imgs/lamp-off.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.pushButton_6.setIcon(icon6)
        self.pushButton_6.setIconSize(QtCore.QSize(70, 70))
        self.pushButton_6.setCheckable(False)
        self.pushButton_6.setChecked(False)
        self.pushButton_6.setObjectName("pushButton_6")

        # QPushButton【运行状态】
        self.pushButton_8 = QtWidgets.QPushButton(self.groupBox_2)
        self.pushButton_8.setGeometry(QtCore.QRect(50, 20, 121, 81))
        self.pushButton_8.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.pushButton_8.setText("")
        icon7 = QtGui.QIcon()
        icon7.addPixmap(QtGui.QPixmap("imgs/lamp-on.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.pushButton_8.setIcon(icon7)
        self.pushButton_8.setIconSize(QtCore.QSize(70, 70))
        self.pushButton_8.setCheckable(False)
        self.pushButton_8.setChecked(False)
        self.pushButton_8.setObjectName("pushButton_8")
        self.pushButton_8.raise_()
        self.pushButton_6.raise_()

        # QCheckBox【mqtt】
        self.checkBox_3 = QtWidgets.QCheckBox(self.centralwidget)
        self.checkBox_3.setGeometry(QtCore.QRect(100, 460, 111, 31))
        self.checkBox_3.setStyleSheet("background-color: rgb(114, 230, 171);")
        icon8 = QtGui.QIcon()
        icon8.addPixmap(QtGui.QPixmap("imgs/notification-filling-off.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        icon8.addPixmap(QtGui.QPixmap("imgs/notification-filling-on.png"), QtGui.QIcon.Normal, QtGui.QIcon.On)
        self.checkBox_3.setIcon(icon8)
        self.checkBox_3.setIconSize(QtCore.QSize(20, 20))
        self.checkBox_3.setCheckable(True)
        self.checkBox_3.setChecked(False)
        self.checkBox_3.setObjectName("checkBox_3")

        # QCheckBox【日志】
        self.checkBox_4 = QtWidgets.QCheckBox(self.centralwidget)
        self.checkBox_4.setGeometry(QtCore.QRect(220, 460, 121, 31))
        self.checkBox_4.setStyleSheet("background-color: rgb(114, 230, 171);")
        icon9 = QtGui.QIcon()
        icon9.addPixmap(QtGui.QPixmap("imgs/file-common-filling.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.checkBox_4.setIcon(icon9)
        self.checkBox_4.setIconSize(QtCore.QSize(20, 20))
        self.checkBox_4.setObjectName("checkBox_4")

        # QTableWidget【传感器类型】
        self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
        self.tableWidget.setEnabled(True)
        self.tableWidget.setGeometry(QtCore.QRect(80, 130, 641, 371))
        self.tableWidget.setBaseSize(QtCore.QSize(0, 0))
        font = QtGui.QFont()
        font.setBold(False)
        font.setWeight(50)
        self.tableWidget.setFont(font)
        self.tableWidget.setStyleSheet("background-color: rgb(153, 153, 0);")
        self.tableWidget.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
        self.tableWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.tableWidget.setDragEnabled(False)
        self.tableWidget.setAlternatingRowColors(False)
        self.tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        self.tableWidget.setGridStyle(QtCore.Qt.SolidLine)
        self.tableWidget.setWordWrap(True)
        self.tableWidget.setRowCount(15)
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.hide()
        self.tableWidget.setColumnCount(6)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(4, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(5, item)
        mainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(mainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 799, 23))
        self.menubar.setObjectName("menubar")
        self.menu = QtWidgets.QMenu(self.menubar)
        self.menu.setObjectName("menu")
        self.menu_2 = QtWidgets.QMenu(self.menubar)
        self.menu_2.setObjectName("menu_2")
        mainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(mainWindow)
        self.statusbar.setObjectName("statusbar")
        mainWindow.setStatusBar(self.statusbar)
        self.menubar.addAction(self.menu.menuAction())
        self.menubar.addAction(self.menu_2.menuAction())

        # 设置按钮点击动作
        self.reTranslateUi(mainWindow)
        self.pushButton_3.clicked.connect(self.pushButton_4.show)
        self.pushButton_3.clicked.connect(mainWindow.start)
        self.pushButton_4.clicked.connect(self.pushButton_4.hide)
        self.pushButton_4.clicked.connect(mainWindow.stop)
        self.pushButton_4.clicked.connect(self.pushButton_3.show)
        self.pushButton_4.clicked.connect(self.pushButton_6.show)
        self.pushButton_5.clicked.connect(mainWindow.close)
        self.pushButton_5.clicked.connect(mainWindow.stop)
        self.pushButton_2.clicked.connect(self.tableWidget.show)
        self.pushButton_2.clicked.connect(self.pushButton_7.show)
        self.pushButton_7.clicked.connect(self.pushButton_2.show)
        self.pushButton_7.clicked.connect(self.tableWidget.hide)
        self.pushButton_2.clicked.connect(self.pushButton_2.hide)
        self.pushButton_7.clicked.connect(self.pushButton_7.hide)
        self.pushButton_3.clicked.connect(self.pushButton_3.hide)
        self.pushButton_3.clicked.connect(self.pushButton_8.show)
        self.pushButton_4.clicked.connect(self.pushButton_8.hide)
        self.pushButton_3.clicked.connect(self.pushButton_6.hide)
        self.checkBox_4.clicked.connect(mainWindow.set_log_flag)
        QtCore.QMetaObject.connectSlotsByName(mainWindow)

    def reTranslateUi(self, mainWindow):
        _translate = QtCore.QCoreApplication.translate
        mainWindow.setWindowTitle(_translate("mainWindow", get_app_name()))
        self.pushButton.setText(_translate("mainWindow", "项目管理"))
        self.pushButton_2.setText(_translate("mainWindow", "设置"))
        self.pushButton_3.setText(_translate("mainWindow", "启动"))
        self.pushButton_4.setText(_translate("mainWindow", "停止"))
        self.pushButton_5.setText(_translate("mainWindow", "退出"))
        self.pushButton_7.setText(_translate("mainWindow", "保存"))
        self.groupBox.setTitle(_translate("mainWindow", "传感器选择"))
        self.checkBox.setText(_translate("mainWindow", "位移"))
        self.checkBox_2.setText(_translate("mainWindow", "应变"))
        self.groupBox_2.setTitle(_translate("mainWindow", "运行状态"))
        self.checkBox_3.setText(_translate("mainWindow", "是否推送MQ"))
        self.checkBox_4.setText(_translate("mainWindow", "是否打开日志"))
        self.checkBox_4.setChecked(True)
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(_translate("mainWindow", "传感器类型"))
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText(_translate("mainWindow", "最大值"))
        item = self.tableWidget.horizontalHeaderItem(2)
        item.setText(_translate("mainWindow", "最小值"))
        item = self.tableWidget.horizontalHeaderItem(3)
        item.setText(_translate("mainWindow", "频率(Hz)"))
        item = self.tableWidget.horizontalHeaderItem(4)
        item.setText(_translate("mainWindow", "数量"))
        item = self.tableWidget.horizontalHeaderItem(5)
        item.setText(_translate("mainWindow", "是否启用"))
        # 在单元格内放置控件
        comBox = QComboBox()
        comBox.addItems([' 应变', ' 位移'])
        comBox.setStyleSheet('QComboBox{margin:3px}')
        self.tableWidget.setCellWidget(0, 0, comBox)
        comBox = QComboBox()
        comBox.addItems([' 1', ' 10', ' 20'])
        comBox.setStyleSheet('QComboBox{margin:3px}')
        self.tableWidget.setCellWidget(0, 3, comBox)

        # 数量
        spinBox = QSpinBox()
        spinBox.setMinimum(1)
        spinBox.setMaximum(500)
        spinBox.setSingleStep(1)
        spinBox.setStyleSheet('QComboBox{margin:3px}')
        self.tableWidget.setCellWidget(0, 4, spinBox)

        # 是否启用
        selectBtn = QPushButton()
        selectBtn.setDown(False)
        selectBtn.setCheckable(True)
        icon4 = QtGui.QIcon()
        icon4.addPixmap(QtGui.QPixmap("imgs/unchecked.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        icon4.addPixmap(QtGui.QPixmap("imgs/checked.png"), QtGui.QIcon.Normal, QtGui.QIcon.On)
        selectBtn.setIcon(icon4)
        selectBtn.setStyleSheet('QPushButton{margin:3px}')
        self.tableWidget.setCellWidget(0, 5, selectBtn)

        self.menu.setTitle(_translate("mainWindow", "项目管理"))
        self.menu_2.setTitle(_translate("mainWindow", "设置"))


class MyWindow(QtWidgets.QMainWindow, Ui_mainWindow):
    msg_utils = []
    intervals = []
    thread_list = []
    conn = None

    def __init__(self):
        super(MyWindow, self).__init__()
        self.setupUi(self)
        configure = Configure()
        msg_conf = configure.get_sensor_conf()
        param_list = []
        # 初始化所有配置信息
        for conf in msg_conf:
            msg_util = MsgUtil(conf)
            # 发送时间间隔(ms)
            interval = conf['interval']
            param_list.append(interval)
            param_list.append(msg_util)
        self.intervals = param_list[::2]
        self.msg_utils = param_list[1::2]
        self.conn = get_rabbit_connection()

    # 启动
    def start(self):
        global stop_flag
        stop_flag = False
        # 初始化所有线程
        for i in range(len(self.intervals)):
            interval = self.intervals[i]
            msg_util = self.msg_utils[i]
            thread = MyThread(i, interval, msg_util)
            self.thread_list.append(thread)
        for thread in self.thread_list:
            thread.start()

    # 停止
    def stop(self):
        global stop_flag
        stop_flag = True
        for thread in self.thread_list:
            thread.stop()
        self.thread_list.clear()

    # 设置日志标志
    @staticmethod
    def set_log_flag():
        global log_flag
        if log_flag:
            log_flag = False
        else:
            log_flag = True

    # 对 QMainWindow 类重写,关闭窗口的时候先把进程关闭
    def closeEvent(self, event):
        """
        重写closeEvent方法,实现 QMainWindow 窗体关闭时执行一些代码
        :param event: close()触发的事件
        :return: None
        """
        reply = QtWidgets.QMessageBox.question(self,
                                               self_name,
                                               "是否要退出程序?",
                                               QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
                                               QtWidgets.QMessageBox.No)
        if reply == QtWidgets.QMessageBox.Yes:
            self.stop()
            event.accept()
        else:
            event.ignore()

    # 加载配置信息
    @staticmethod
    def load_conf(sp):
        splash.show()
        for i in range(1, 11):  # 模拟主程序加载过程
            time.sleep(0.3)  # 加载数据
            sp.showMessage("Loading... {0}%".format(i * 10), QtCore.Qt.AlignHCenter | QtCore.Qt.AlignBottom, QtCore.Qt.black)
            QtWidgets.qApp.processEvents()  # 允许主进程处理事件
        splash.close()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    splash = QtWidgets.QSplashScreen(QtGui.QPixmap("imgs/load-2.png"))
    splash.showMessage("Loading... 0%", QtCore.Qt.AlignHCenter | QtCore.Qt.AlignBottom, QtCore.Qt.black)
    window = MyWindow()
    window.show()
    window.load_conf(splash)
    sys.exit(app.exec_())
  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-09-01 12:00:29  更:2021-09-01 12:01:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 17:06:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码