PyQt5+Serial+pypyodbc+win32com实现监听扫描枪串口,从ACCESS数据库中获取数据写入Excel自动打印

  • 项目简介
    我公司是生产制造公司,每切换一个订单,员工需要手动填写生产记录表,填写内容包括 订单号、产品管理编号、产品名称、产品尺寸、产品类别、宽度、厚度、长度、基准重量、订单数量 等等大量信息。人工书写易出错,浪费时间。事实上,设想,我公司产品数据都保存在ACCESS数据库中,只要通过 扫描枪获取产品管理编号 便可从数据库中获取其余信息,之后将所有信息写入Excel自动打印即可。
  • 关键代码如下
    ①使用PyQt5创建操作界面(为的是选取日期及核对信息用,其实没有界面也可以。Pyqt不是本次介绍重点,此处代码过于繁琐,省略。)界面如下:
    在这里插入图片描述
    ②使用Serial获取扫描枪数据
    扫描枪淘宝上60几块的带USB串口功能的就可以。参照扫描枪说明书将其设置为USB串口模式。
    在电脑设备管理器中确认扫描枪的端口号,我的是COM3。端口号也可以在设备管理器中更改。
		# 此处需要导入的模块
		import serial
		import sound,winsound
		
		try:
        	# 创建Serial对象,参数为(端口号,波特率,超时时间) 为防止出错此处使用try except
            ser = serial.Serial("com3", 9600, timeout=0.5)
        except Exception as e:
            # 在D盘创建了一个错误日志,如果连接串口失败,则写入此日志。
            f = open('d:/err_info.txt', 'a')
            f.writelines(str(datetime.datetime.now()))
            f.writelines(repr(e))
            f.writelines('\r\n')
            f.close()
            ser = ''
            
            '''此处是我在本地存了一个语音错误播报音频,当出现错误时调用此音频文件,
            有需要的朋友可以到https://app.xunjiepdf.com/text2voice/进行在线转换。'''
            com3_not_found_sound_path = sound_path + 'COM3_not_found.wav'
            sound.play(com3_not_found_sound_path, winsound.SND_ALIAS)

		# 从串口对象中获取数据
        def receive(ser):
            data = ''
            try:
                while ser.inWaiting() > 0:
                	# 因为串口获取的数据类型为byte此处需要decode转换
                    data += ser.read().decode()
                return data
            except Exception as e:
                return data
                # 我设置的条形码格式为 订单号|产品编号|数量 (例:123456|CMF120-19|100)
                # 注意:条形码扫描枪仅支持英文,不支持中文。

③从ACCESS数据库中获取数据存入EXCEL
因为access数据库放在公司服务器中,如果没网的话就无法正常使用,所以我的做法是将所有数据存入到EXCEL中,仅在每次打开pyqt窗体时执行数据更新。这样平时可以使用EXCEL中的数据进行查询

此处需要导入的模块

import pypyodbc
import pandas as pd
import openpyxl
import datetime
import sound
import winsound
import time
import win32com.client

创建方法,用来获取access的数据。(因为我需要的数据在两个表中,要调用两次,所以写此方法方便调用)

# 获取access的数据。
def get_table(product_info_path, sql, names,PWD, sound_path=''):
    try:
        file_path = product_info_path
        # conn = pypyodbc.win_connect_mdb(u'Driver={Microsoft Access Driver (*.mdb, *.accdb)};PWD=8110;DBQ=' + file_path)
        conn_str = 'Driver={Microsoft Access Driver (*.mdb, *.accdb)};PWD=%s;DBQ=%s'%(PWD,file_path)
        conn = pypyodbc.connect(conn_str)
        cursor = conn.cursor()
        cursor.execute(sql)
        data = cursor.fetchall()
        df = pd.DataFrame(data, columns=names)
        return df
    except Exception as e:
        f = open('d:/err_info.txt', 'a')
        f.writelines(str(datetime.datetime.now()))
        f.writelines(repr(e))
        f.writelines('\r\n')

        print(e.args)
        return ""

将两个表的数据连接起来

def link_table(parent_access_path, product_info_path,PWD, sound_path=''):
    try:
        # 获取产品信息表
        parent_access_path = parent_access_path
        sql = "select 管理编号,名称,尺寸 from 产品列表"
        names = ['管理编号', '名称', '尺寸']
        df1 = get_table(parent_access_path, sql, names,PWD)

        # 获取式样书
        product_info_path = product_info_path
        sql = "select 管理编号,[50cm重量],[50cm重量下限],[50cm重量上限],[製品厚み],厚度许可范围下限,厚度许可范围上限,原反幅,原反幅基準下限," \
              "原反幅基準上限,インフレ幅,製品長さ,原反基准重量,原反基准重量上限,原反基准重量下限 from 现有防锈龙 union select 管理编号,'0'," \
              "'0','0',[製品厚み],厚度许可范围下限,厚度许可范围上限,原反幅,原反幅基準下限,原反幅基準上限,インフレ幅,製品長さ,原反基准重量," \
              "原反基准重量上限,原反基准重量下限 from 现有一般PE"
        names = ['管理编号', '50cm重量', '50cm重量下限', '50cm重量上限', '製品厚み', '厚度许可范围下限', '厚度许可范围上限', '原反幅', '原反幅基準下限', '原反幅基準上限',
                 'インフレ幅', '製品長さ', '原反基准重量', '原反基准重量上限', '原反基准重量下限']
        # 数字类型需转换为文本后才可以连接
        df2 = get_table(product_info_path, sql, names,PWD)
        # df2['50cm重量上限'] = df2['50cm重量上限'].apply(str)

        # 连接表
        rs = pd.merge(df1, df2, how='left', on=['管理编号', '管理编号'])
        # 字段为空无法使用contains函数
        # rs['类别'] = rs['类别'].apply(str)
        # rs = rs.loc[rs['类别'].str.contains('卷材', regex=True)]
        # print(rs)
        return rs
    except Exception as e:
        f = open('d:/err_info.txt', 'a')
        f.writelines(str(datetime.datetime.now()))
        f.writelines(repr(e))
        f.writelines('\r\n')
        print(e.args)
        return ''

将数据保存到需要打印的Excel中的data表中

# 从access更新数据库写入excel
def from_access_update_into_excel_xlsx(parent_access_path, product_info_path, database_path, PWD,sound_path):
    try:
        time = datetime.datetime.now().replace(microsecond=0)
        rs = link_table(parent_access_path, product_info_path,PWD)

        rs.to_excel(database_path, sheet_name='data')
        sound_path += 'database_update_successfully.wav'
        sound.play(sound_path, winsound.SND_ALIAS)
        return "数据库更新成功!在: %s" % (time)
    except Exception as e:
        f = open('d:/err_info.txt', 'a')
        f.writelines(str(datetime.datetime.now()))
        f.writelines(repr(e))
        f.writelines('\r\n')

        sound_path += 'database_update_failed.wav'
        sound.play(sound_path, winsound.SND_ALIAS)
        print(sound_path)
        return "数据库更新失败!在: %s" % (time)

③win32api实现自动打印

# 写入扫描信息到Excel
def scan_val_to_excel(print_file_path, jilubiao_sheet_name, jilubiao_area, rukudan_sheet_name, rukudan_area,
                      lis_jilubiao, lis_rukudan, sound_path, print_mode):
    message = ''
    print('开始传输到excel并打印')
    print('mode:'+print_mode)
    try:
        xlApp = win32com.client.Dispatch('Excel.Application')  # 打开EXCEL,这里不需改动
        xlBook = xlApp.Workbooks.Open(print_file_path)  # 将dir改为要处理的excel文件路径
        xlSht1 = xlBook.Worksheets(jilubiao_sheet_name)  # 要处理的excel页
        xlSht2 = xlBook.Worksheets(rukudan_sheet_name)  # 要处理的excel页
        for item in lis_rukudan:
            xlSht2.Cells(item[0][0], item[0][1]).value = ''
            xlSht2.Cells(item[0][0], item[0][1]).value = item[1]

        for item in lis_jilubiao:
            xlSht1.Cells(item[0][0], item[0][1]).value = ''
            xlSht1.Cells(item[0][0], item[0][1]).value = item[1]
        if print_mode == '1':
            xlSht1.PrintOut()
            xlSht2.PrintOut()
        elif print_mode == '2':
            xlSht1.PrintOut()
        else:
            xlSht2.PrintOut()
        xlBook.Close(SaveChanges=0)  # 完成 关闭保存文件
        now = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
        message = '成功写入Excel。已传送至打印机。在:%s'%now
        sound_path += 'printing.wav'
        sound.play(sound_path, winsound.SND_ALIAS)
        return message
    except Exception as e:
        f = open('d:/err_info.txt', 'a')
        f.writelines(str(datetime.datetime.now()))
        f.writelines(repr(e))
        f.writelines('\r\n')
        print(e.args)
        message = '打印传输未知错误。'
        sound_path += 'printing_failed.wav'
        sound.play(sound_path, winsound.SND_ALIAS)
        if xlBook:
            xlBook.Close(SaveChanges=0)
        return message
    finally:
        print('打印传输完毕')

代码有点多,完整代码如下:

AutoPrintSystem.py模块代码:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'AutoPrintSystem.ui'
#
# Created by: PyQt5 UI code generator 5.13.2
#
# WARNING! All changes made in this file will be lost!


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.setEnabled(True)
        MainWindow.resize(518, 563)
        MainWindow.setMinimumSize(QtCore.QSize(518, 563))
        MainWindow.setMaximumSize(QtCore.QSize(518, 563))
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("../../favicon.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        MainWindow.setWindowIcon(icon)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.frame = QtWidgets.QFrame(self.centralwidget)
        self.frame.setGeometry(QtCore.QRect(100, 110, 391, 351))
        self.frame.setFrameShape(QtWidgets.QFrame.Box)
        self.frame.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.frame.setMidLineWidth(0)
        self.frame.setObjectName("frame")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.frame)
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout_23 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_23.setObjectName("horizontalLayout_23")
        self.label_7 = QtWidgets.QLabel(self.frame)
        self.label_7.setObjectName("label_7")
        self.horizontalLayout_23.addWidget(self.label_7)
        self.lineEdit_7 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_7.setMinimumSize(QtCore.QSize(150, 0))
        self.lineEdit_7.setReadOnly(False)
        self.lineEdit_7.setObjectName("lineEdit_7")
        self.horizontalLayout_23.addWidget(self.lineEdit_7)
        self.label_43 = QtWidgets.QLabel(self.frame)
        self.label_43.setMinimumSize(QtCore.QSize(53, 0))
        self.label_43.setMaximumSize(QtCore.QSize(100, 16777215))
        self.label_43.setObjectName("label_43")
        self.horizontalLayout_23.addWidget(self.label_43)
        self.lineEdit_40 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_40.setMinimumSize(QtCore.QSize(0, 0))
        self.lineEdit_40.setMaximumSize(QtCore.QSize(1000, 16777215))
        self.lineEdit_40.setReadOnly(False)
        self.lineEdit_40.setObjectName("lineEdit_40")
        self.horizontalLayout_23.addWidget(self.lineEdit_40)
        self.verticalLayout.addLayout(self.horizontalLayout_23)
        self.horizontalLayout_6 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_6.setObjectName("horizontalLayout_6")
        self.label_2 = QtWidgets.QLabel(self.frame)
        self.label_2.setObjectName("label_2")
        self.horizontalLayout_6.addWidget(self.label_2)
        self.lineEdit_2 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_2.setMinimumSize(QtCore.QSize(140, 0))
        self.lineEdit_2.setMaximumSize(QtCore.QSize(1000, 16777215))
        self.lineEdit_2.setReadOnly(False)
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.horizontalLayout_6.addWidget(self.lineEdit_2)
        self.verticalLayout.addLayout(self.horizontalLayout_6)
        self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_7.setObjectName("horizontalLayout_7")
        self.label_5 = QtWidgets.QLabel(self.frame)
        self.label_5.setObjectName("label_5")
        self.horizontalLayout_7.addWidget(self.label_5)
        self.lineEdit_5 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_5.setMinimumSize(QtCore.QSize(100, 0))
        self.lineEdit_5.setReadOnly(False)
        self.lineEdit_5.setObjectName("lineEdit_5")
        self.horizontalLayout_7.addWidget(self.lineEdit_5)
        self.verticalLayout.addLayout(self.horizontalLayout_7)
        self.horizontalLayout_8 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_8.setObjectName("horizontalLayout_8")
        self.label_6 = QtWidgets.QLabel(self.frame)
        self.label_6.setObjectName("label_6")
        self.horizontalLayout_8.addWidget(self.label_6)
        self.lineEdit_6 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_6.setMinimumSize(QtCore.QSize(100, 0))
        self.lineEdit_6.setText("")
        self.lineEdit_6.setReadOnly(False)
        self.lineEdit_6.setObjectName("lineEdit_6")
        self.horizontalLayout_8.addWidget(self.lineEdit_6)
        self.verticalLayout.addLayout(self.horizontalLayout_8)
        self.line = QtWidgets.QFrame(self.frame)
        self.line.setFrameShape(QtWidgets.QFrame.HLine)
        self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line.setObjectName("line")
        self.verticalLayout.addWidget(self.line)
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.label_9 = QtWidgets.QLabel(self.frame)
        self.label_9.setObjectName("label_9")
        self.horizontalLayout_4.addWidget(self.label_9)
        self.lineEdit_3 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_3.setObjectName("lineEdit_3")
        self.horizontalLayout_4.addWidget(self.lineEdit_3)
        self.label_11 = QtWidgets.QLabel(self.frame)
        self.label_11.setObjectName("label_11")
        self.horizontalLayout_4.addWidget(self.label_11)
        self.lineEdit_8 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_8.setObjectName("lineEdit_8")
        self.horizontalLayout_4.addWidget(self.lineEdit_8)
        self.label_10 = QtWidgets.QLabel(self.frame)
        self.label_10.setObjectName("label_10")
        self.horizontalLayout_4.addWidget(self.label_10)
        self.lineEdit_4 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_4.setObjectName("lineEdit_4")
        self.horizontalLayout_4.addWidget(self.lineEdit_4)
        self.verticalLayout.addLayout(self.horizontalLayout_4)
        self.horizontalLayout_24 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_24.setObjectName("horizontalLayout_24")
        self.label_44 = QtWidgets.QLabel(self.frame)
        self.label_44.setObjectName("label_44")
        self.horizontalLayout_24.addWidget(self.label_44)
        self.lineEdit_41 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_41.setObjectName("lineEdit_41")
        self.horizontalLayout_24.addWidget(self.lineEdit_41)
        self.label_46 = QtWidgets.QLabel(self.frame)
        self.label_46.setObjectName("label_46")
        self.horizontalLayout_24.addWidget(self.label_46)
        self.lineEdit_43 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_43.setObjectName("lineEdit_43")
        self.horizontalLayout_24.addWidget(self.lineEdit_43)
        self.label_45 = QtWidgets.QLabel(self.frame)
        self.label_45.setObjectName("label_45")
        self.horizontalLayout_24.addWidget(self.label_45)
        self.lineEdit_42 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_42.setObjectName("lineEdit_42")
        self.horizontalLayout_24.addWidget(self.lineEdit_42)
        self.verticalLayout.addLayout(self.horizontalLayout_24)
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.label_12 = QtWidgets.QLabel(self.frame)
        self.label_12.setObjectName("label_12")
        self.horizontalLayout_5.addWidget(self.label_12)
        self.lineEdit_9 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_9.setObjectName("lineEdit_9")
        self.horizontalLayout_5.addWidget(self.lineEdit_9)
        self.label_14 = QtWidgets.QLabel(self.frame)
        self.label_14.setObjectName("label_14")
        self.horizontalLayout_5.addWidget(self.label_14)
        self.lineEdit_11 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_11.setObjectName("lineEdit_11")
        self.horizontalLayout_5.addWidget(self.lineEdit_11)
        self.label_13 = QtWidgets.QLabel(self.frame)
        self.label_13.setObjectName("label_13")
        self.horizontalLayout_5.addWidget(self.label_13)
        self.lineEdit_10 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_10.setObjectName("lineEdit_10")
        self.horizontalLayout_5.addWidget(self.lineEdit_10)
        self.verticalLayout.addLayout(self.horizontalLayout_5)
        self.horizontalLayout_11 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_11.setObjectName("horizontalLayout_11")
        self.label_18 = QtWidgets.QLabel(self.frame)
        self.label_18.setObjectName("label_18")
        self.horizontalLayout_11.addWidget(self.label_18)
        self.lineEdit_15 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_15.setObjectName("lineEdit_15")
        self.horizontalLayout_11.addWidget(self.lineEdit_15)
        self.label_20 = QtWidgets.QLabel(self.frame)
        self.label_20.setObjectName("label_20")
        self.horizontalLayout_11.addWidget(self.label_20)
        self.lineEdit_17 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_17.setObjectName("lineEdit_17")
        self.horizontalLayout_11.addWidget(self.lineEdit_17)
        self.label_19 = QtWidgets.QLabel(self.frame)
        self.label_19.setObjectName("label_19")
        self.horizontalLayout_11.addWidget(self.label_19)
        self.lineEdit_16 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_16.setObjectName("lineEdit_16")
        self.horizontalLayout_11.addWidget(self.lineEdit_16)
        self.verticalLayout.addLayout(self.horizontalLayout_11)
        self.horizontalLayout_12 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_12.setObjectName("horizontalLayout_12")
        self.label_21 = QtWidgets.QLabel(self.frame)
        self.label_21.setObjectName("label_21")
        self.horizontalLayout_12.addWidget(self.label_21)
        self.lineEdit_18 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_18.setObjectName("lineEdit_18")
        self.horizontalLayout_12.addWidget(self.lineEdit_18)
        self.label_23 = QtWidgets.QLabel(self.frame)
        self.label_23.setObjectName("label_23")
        self.horizontalLayout_12.addWidget(self.label_23)
        self.lineEdit_20 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_20.setObjectName("lineEdit_20")
        self.horizontalLayout_12.addWidget(self.lineEdit_20)
        self.label_22 = QtWidgets.QLabel(self.frame)
        self.label_22.setObjectName("label_22")
        self.horizontalLayout_12.addWidget(self.label_22)
        self.lineEdit_19 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_19.setObjectName("lineEdit_19")
        self.horizontalLayout_12.addWidget(self.lineEdit_19)
        self.verticalLayout.addLayout(self.horizontalLayout_12)
        self.horizontalLayout_10 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_10.setObjectName("horizontalLayout_10")
        self.label_15 = QtWidgets.QLabel(self.frame)
        self.label_15.setObjectName("label_15")
        self.horizontalLayout_10.addWidget(self.label_15)
        self.lineEdit_12 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_12.setObjectName("lineEdit_12")
        self.horizontalLayout_10.addWidget(self.lineEdit_12)
        self.label_17 = QtWidgets.QLabel(self.frame)
        self.label_17.setObjectName("label_17")
        self.horizontalLayout_10.addWidget(self.label_17)
        self.lineEdit_14 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_14.setObjectName("lineEdit_14")
        self.horizontalLayout_10.addWidget(self.lineEdit_14)
        self.label_16 = QtWidgets.QLabel(self.frame)
        self.label_16.setObjectName("label_16")
        self.horizontalLayout_10.addWidget(self.label_16)
        self.lineEdit_13 = QtWidgets.QLineEdit(self.frame)
        self.lineEdit_13.setObjectName("lineEdit_13")
        self.horizontalLayout_10.addWidget(self.lineEdit_13)
        self.verticalLayout.addLayout(self.horizontalLayout_10)
        self.layoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.layoutWidget.setGeometry(QtCore.QRect(150, 460, 341, 41))
        self.layoutWidget.setObjectName("layoutWidget")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.layoutWidget)
        self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.radioButton = QtWidgets.QRadioButton(self.layoutWidget)
        self.radioButton.setObjectName("radioButton")
        self.horizontalLayout_2.addWidget(self.radioButton)
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem)
        self.radioButton_2 = QtWidgets.QRadioButton(self.layoutWidget)
        self.radioButton_2.setObjectName("radioButton_2")
        self.horizontalLayout_2.addWidget(self.radioButton_2)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem1)
        self.radioButton_3 = QtWidgets.QRadioButton(self.layoutWidget)
        self.radioButton_3.setObjectName("radioButton_3")
        self.horizontalLayout_2.addWidget(self.radioButton_3)
        self.layoutWidget1 = QtWidgets.QWidget(self.centralwidget)
        self.layoutWidget1.setGeometry(QtCore.QRect(30, 0, 461, 51))
        self.layoutWidget1.setObjectName("layoutWidget1")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.layoutWidget1)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.label = QtWidgets.QLabel(self.layoutWidget1)
        self.label.setMouseTracking(True)
        self.label.setObjectName("label")
        self.horizontalLayout.addWidget(self.label)
        self.lineEdit = QtWidgets.QLineEdit(self.layoutWidget1)
        self.lineEdit.setEnabled(True)
        font = QtGui.QFont()
        font.setFamily("Calibri")
        font.setPointSize(7)
        font.setItalic(True)
        self.lineEdit.setFont(font)
        self.lineEdit.setText("")
        self.lineEdit.setReadOnly(True)
        self.lineEdit.setObjectName("lineEdit")
        self.horizontalLayout.addWidget(self.lineEdit)
        self.listWidget = QtWidgets.QListWidget(self.centralwidget)
        self.listWidget.setGeometry(QtCore.QRect(30, 110, 61, 351))
        self.listWidget.setObjectName("listWidget")
        self.line_2 = QtWidgets.QFrame(self.centralwidget)
        self.line_2.setGeometry(QtCore.QRect(0, 500, 531, 16))
        self.line_2.setFrameShadow(QtWidgets.QFrame.Raised)
        self.line_2.setLineWidth(1)
        self.line_2.setMidLineWidth(0)
        self.line_2.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_2.setObjectName("line_2")
        self.layoutWidget_2 = QtWidgets.QWidget(self.centralwidget)
        self.layoutWidget_2.setGeometry(QtCore.QRect(390, 60, 101, 39))
        self.layoutWidget_2.setObjectName("layoutWidget_2")
        self.horizontalLayout_14 = QtWidgets.QHBoxLayout(self.layoutWidget_2)
        self.horizontalLayout_14.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_14.setObjectName("horizontalLayout_14")
        self.radioButton_6 = QtWidgets.QRadioButton(self.layoutWidget_2)
        font = QtGui.QFont()
        font.setFamily("华文楷体")
        font.setPointSize(10)
        self.radioButton_6.setFont(font)
        self.radioButton_6.setObjectName("radioButton_6")
        self.horizontalLayout_14.addWidget(self.radioButton_6)
        self.radioButton_7 = QtWidgets.QRadioButton(self.layoutWidget_2)
        font = QtGui.QFont()
        font.setFamily("华文楷体")
        font.setPointSize(10)
        self.radioButton_7.setFont(font)
        self.radioButton_7.setObjectName("radioButton_7")
        self.horizontalLayout_14.addWidget(self.radioButton_7)
        self.widget = QtWidgets.QWidget(self.centralwidget)
        self.widget.setGeometry(QtCore.QRect(230, 60, 101, 39))
        self.widget.setObjectName("widget")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.widget)
        self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.radioButton_4 = QtWidgets.QRadioButton(self.widget)
        font = QtGui.QFont()
        font.setFamily("华文楷体")
        font.setPointSize(10)
        self.radioButton_4.setFont(font)
        self.radioButton_4.setObjectName("radioButton_4")
        self.horizontalLayout_3.addWidget(self.radioButton_4)
        self.radioButton_5 = QtWidgets.QRadioButton(self.widget)
        font = QtGui.QFont()
        font.setFamily("华文楷体")
        font.setPointSize(10)
        self.radioButton_5.setFont(font)
        self.radioButton_5.setObjectName("radioButton_5")
        self.horizontalLayout_3.addWidget(self.radioButton_5)
        self.widget1 = QtWidgets.QWidget(self.centralwidget)
        self.widget1.setGeometry(QtCore.QRect(30, 60, 211, 39))
        self.widget1.setObjectName("widget1")
        self.horizontalLayout_13 = QtWidgets.QHBoxLayout(self.widget1)
        self.horizontalLayout_13.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_13.setObjectName("horizontalLayout_13")
        self.label_8 = QtWidgets.QLabel(self.widget1)
        self.label_8.setMinimumSize(QtCore.QSize(0, 0))
        self.label_8.setMaximumSize(QtCore.QSize(40, 16777215))
        font = QtGui.QFont()
        font.setFamily("华文楷体")
        font.setPointSize(10)
        self.label_8.setFont(font)
        self.label_8.setObjectName("label_8")
        self.horizontalLayout_13.addWidget(self.label_8)
        self.dateEdit = QtWidgets.QDateEdit(self.widget1)
        self.dateEdit.setMinimumSize(QtCore.QSize(100, 0))
        self.dateEdit.setMaximumSize(QtCore.QSize(500, 16777215))
        font = QtGui.QFont()
        font.setFamily("华文楷体")
        font.setPointSize(10)
        self.dateEdit.setFont(font)
        self.dateEdit.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.dateEdit.setProperty("showGroupSeparator", False)
        self.dateEdit.setCalendarPopup(True)
        self.dateEdit.setDate(QtCore.QDate(1992, 1, 1))
        self.dateEdit.setObjectName("dateEdit")
        self.horizontalLayout_13.addWidget(self.dateEdit)
        self.frame_2 = QtWidgets.QFrame(self.widget1)
        self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_2.setObjectName("frame_2")
        self.horizontalLayout_13.addWidget(self.frame_2)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menuBar = QtWidgets.QMenuBar(MainWindow)
        self.menuBar.setGeometry(QtCore.QRect(0, 0, 518, 29))
        font = QtGui.QFont()
        font.setFamily("Segoe Print")
        font.setPointSize(8)
        self.menuBar.setFont(font)
        self.menuBar.setContextMenuPolicy(QtCore.Qt.NoContextMenu)
        self.menuBar.setToolTip("")
        self.menuBar.setObjectName("menuBar")
        self.menu = QtWidgets.QMenu(self.menuBar)
        font = QtGui.QFont()
        font.setFamily("Segoe Print")
        font.setPointSize(8)
        self.menu.setFont(font)
        self.menu.setObjectName("menu")
        MainWindow.setMenuBar(self.menuBar)
        self.statusBar = QtWidgets.QStatusBar(MainWindow)
        font = QtGui.QFont()
        font.setFamily("仿宋")
        self.statusBar.setFont(font)
        self.statusBar.setObjectName("statusBar")
        MainWindow.setStatusBar(self.statusBar)
        self.actionUpdate_database = QtWidgets.QAction(MainWindow)
        self.actionUpdate_database.setObjectName("actionUpdate_database")
        self.menu.addAction(self.actionUpdate_database)
        self.menuBar.addAction(self.menu.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        MainWindow.setTabOrder(self.lineEdit_2, self.lineEdit_5)
        MainWindow.setTabOrder(self.lineEdit_5, self.lineEdit_6)
        MainWindow.setTabOrder(self.lineEdit_6, self.radioButton)
        MainWindow.setTabOrder(self.radioButton, self.radioButton_2)
        MainWindow.setTabOrder(self.radioButton_2, self.radioButton_3)
        MainWindow.setTabOrder(self.radioButton_3, self.lineEdit)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "记录表打印工具_v1.0_202005"))
        self.label_7.setText(_translate("MainWindow", "订单号  "))
        self.label_43.setText(_translate("MainWindow", " 指示数"))
        self.label_2.setText(_translate("MainWindow", "管理编号"))
        self.label_5.setText(_translate("MainWindow", "产品名称"))
        self.label_6.setText(_translate("MainWindow", "产品尺寸"))
        self.label_9.setText(_translate("MainWindow", "基重"))
        self.label_11.setText(_translate("MainWindow", "下限"))
        self.label_10.setText(_translate("MainWindow", "上限"))
        self.label_44.setText(_translate("MainWindow", "PE厚"))
        self.label_46.setText(_translate("MainWindow", "下限"))
        self.label_45.setText(_translate("MainWindow", "上限"))
        self.label_12.setText(_translate("MainWindow", "宽度"))
        self.label_14.setText(_translate("MainWindow", "下限"))
        self.label_13.setText(_translate("MainWindow", "上限"))
        self.label_18.setText(_translate("MainWindow", "筒款"))
        self.label_20.setText(_translate("MainWindow", "下限"))
        self.label_19.setText(_translate("MainWindow", "上限"))
        self.label_21.setText(_translate("MainWindow", "卷长"))
        self.label_23.setText(_translate("MainWindow", "下限"))
        self.label_22.setText(_translate("MainWindow", "上限"))
        self.label_15.setText(_translate("MainWindow", "卷重"))
        self.label_17.setText(_translate("MainWindow", "下限"))
        self.label_16.setText(_translate("MainWindow", "上限"))
        self.radioButton.setText(_translate("MainWindow", "记录表和入库单"))
        self.radioButton_2.setText(_translate("MainWindow", "仅记录表"))
        self.radioButton_3.setText(_translate("MainWindow", "仅入库单"))
        self.label.setText(_translate("MainWindow", "扫描代码:"))
        self.lineEdit.setPlaceholderText(_translate("MainWindow", "请使用扫码器扫描"))
        self.radioButton_6.setText(_translate("MainWindow", "甲"))
        self.radioButton_7.setText(_translate("MainWindow", "乙"))
        self.radioButton_4.setText(_translate("MainWindow", "早"))
        self.radioButton_5.setText(_translate("MainWindow", "夜"))
        self.label_8.setText(_translate("MainWindow", "日期:"))
        self.menu.setTitle(_translate("MainWindow", "Setting"))
        self.actionUpdate_database.setText(_translate("MainWindow", "Update database"))

data_handle.py模块代码

import pypyodbc
import pandas as pd
import re
import tkinter
from tkinter import messagebox
import openpyxl
import pywin32_system32
import win32api
import win32print
import datetime
import sound
import winsound
import time
import gc
import win32com.client


# 连接access获取数据
def get_table(product_info_path, sql, names,PWD, sound_path=''):
    try:
        file_path = product_info_path
        # conn = pypyodbc.win_connect_mdb(u'Driver={Microsoft Access Driver (*.mdb, *.accdb)};PWD=8110;DBQ=' + file_path)
        conn_str = 'Driver={Microsoft Access Driver (*.mdb, *.accdb)};PWD=%s;DBQ=%s'%(PWD,file_path)
        conn = pypyodbc.connect(conn_str)
        cursor = conn.cursor()
        cursor.execute(sql)
        data = cursor.fetchall()
        df = pd.DataFrame(data, columns=names)
        return df
    except Exception as e:
        f = open('d:/err_info.txt', 'a')
        f.writelines(str(datetime.datetime.now()))
        f.writelines(repr(e))
        f.writelines('\r\n')

        print(e.args)
        return ""


def link_table(parent_access_path, product_info_path,PWD, sound_path=''):
    try:
        # 获取产品信息表
        parent_access_path = parent_access_path
        sql = "select 管理编号,名称,尺寸 from 产品列表"
        names = ['管理编号', '名称', '尺寸']
        df1 = get_table(parent_access_path, sql, names,PWD)

        # 获取式样书
        product_info_path = product_info_path
        sql = "select 管理编号,[50cm重量],[50cm重量下限],[50cm重量上限],[製品厚み],厚度许可范围下限,厚度许可范围上限,原反幅,原反幅基準下限," \
              "原反幅基準上限,インフレ幅,製品長さ,原反基准重量,原反基准重量上限,原反基准重量下限 from 现有防锈龙 union select 管理编号,'0'," \
              "'0','0',[製品厚み],厚度许可范围下限,厚度许可范围上限,原反幅,原反幅基準下限,原反幅基準上限,インフレ幅,製品長さ,原反基准重量," \
              "原反基准重量上限,原反基准重量下限 from 现有一般PE"
        names = ['管理编号', '50cm重量', '50cm重量下限', '50cm重量上限', '製品厚み', '厚度许可范围下限', '厚度许可范围上限', '原反幅', '原反幅基準下限', '原反幅基準上限',
                 'インフレ幅', '製品長さ', '原反基准重量', '原反基准重量上限', '原反基准重量下限']
        # 数字类型需转换为文本后才可以连接
        df2 = get_table(product_info_path, sql, names,PWD)
        # df2['50cm重量上限'] = df2['50cm重量上限'].apply(str)

        # 连接表
        rs = pd.merge(df1, df2, how='left', on=['管理编号', '管理编号'])
        # 字段为空无法使用contains函数
        # rs['类别'] = rs['类别'].apply(str)
        # rs = rs.loc[rs['类别'].str.contains('卷材', regex=True)]
        # print(rs)
        return rs
    except Exception as e:
        f = open('d:/err_info.txt', 'a')
        f.writelines(str(datetime.datetime.now()))
        f.writelines(repr(e))
        f.writelines('\r\n')

        print(e.args)
        return ''


# link_table("C:/Users/john/Desktop/axl/AXL产品数据库-后端.accdb","C:/Users/john/Desktop/提示音/failed.wav")


# 从access更新数据库写入excel
def from_access_update_into_excel_xlsx(parent_access_path, product_info_path, database_path, PWD,sound_path):
    try:
        time = datetime.datetime.now().replace(microsecond=0)
        rs = link_table(parent_access_path, product_info_path,PWD)

        rs.to_excel(database_path, sheet_name='data')
        sound_path += 'database_update_successfully.wav'
        sound.play(sound_path, winsound.SND_ALIAS)
        return "数据库更新成功!在: %s" % (time)
    except Exception as e:
        f = open('d:/err_info.txt', 'a')
        f.writelines(str(datetime.datetime.now()))
        f.writelines(repr(e))
        f.writelines('\r\n')

        sound_path += 'database_update_failed.wav'
        sound.play(sound_path, winsound.SND_ALIAS)
        print(sound_path)
        return "数据库更新失败!在: %s" % (time)
    #

# 写入扫描信息到Excel
def scan_val_to_excel(print_file_path, jilubiao_sheet_name, jilubiao_area, rukudan_sheet_name, rukudan_area,
                      lis_jilubiao, lis_rukudan, sound_path, print_mode):
    # messagebox.showinfo('提示', '成功')
    # win32api.ShellExecute(0, 'open', 'http://www.baidu.com', '1','',1)
    # win32api.ShellExecute(0, 'open', 'notepad.exe', '','',0)
    message = ''
    print('开始传输到excel并打印')
    print('mode:'+print_mode)
    try:
        xlApp = win32com.client.Dispatch('Excel.Application')  # 打开EXCEL,这里不需改动
        xlBook = xlApp.Workbooks.Open(print_file_path)  # 将dir改为要处理的excel文件路径
        xlSht1 = xlBook.Worksheets(jilubiao_sheet_name)  # 要处理的excel页
        xlSht2 = xlBook.Worksheets(rukudan_sheet_name)  # 要处理的excel页
        # wb = openpyxl.load_workbook(print_file_path)
        # jilubiao_sheet = wb[jilubiao_sheet_name]
        # rukudan_sheet = wb[rukudan_sheet_name]
        for item in lis_rukudan:
            xlSht2.Cells(item[0][0], item[0][1]).value = ''
            xlSht2.Cells(item[0][0], item[0][1]).value = item[1]

        for item in lis_jilubiao:
            xlSht1.Cells(item[0][0], item[0][1]).value = ''
            xlSht1.Cells(item[0][0], item[0][1]).value = item[1]

            # jilubiao_sheet.cell(item[0][0], item[0][1], '')
            # jilubiao_sheet.cell(item[0][0], item[0][1], item[1])
        # wb.save(print_file_path)
        # jilubiao_sheet.print_area = jilubiao_area
        # jilubiao_sheet.print_options.horizontalCentered = True  # 水平居中
        # jilubiao_sheet.print_options.verticalCentered = True  # 垂直居中
        # rukudan_sheet.print_area = rukudan_area
        # rukudan_sheet.print_options.horizontalCentered = True  # 水平居中
        # rukudan_sheet.print_options.verticalCentered = True  # 垂直居中
        if print_mode == '1':
            xlSht1.PrintOut()
            xlSht2.PrintOut()
            # wb.active =jilubiao_sheet
            # wb.save(print_file_path)
            # win32api.ShellExecute(0, "print", print_file_path, win32print.GetDefaultPrinter(), "", 0)
            # wb.active =rukudan_sheet
            # wb.save(print_file_path)
            # win32api.ShellExecute(0, "print", print_file_path, win32print.GetDefaultPrinter(), "", 0)
        elif print_mode == '2':
            xlSht1.PrintOut()
            # wb.active =0
            # wb.save(print_file_path)
            # win32api.ShellExecute(0, "print", print_file_path, win32print.GetDefaultPrinter(), "", 0)
        else:
            xlSht2.PrintOut()
            # wb.active =rukudan_sheet
            # wb.save(print_file_path)
            # win32api.ShellExecute(0, "print", print_file_path, win32print.GetDefaultPrinter(), "", 0)
        # ws.print_area = 'B2:AT36'  # 设置打印区域
        # ws.print_options.horizontalCentered = True  # 水平居中
        # ws.print_options.verticalCentered = True  # 垂直居中
        xlBook.Close(SaveChanges=0)  # 完成 关闭保存文件
        now = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
        message = '成功写入Excel。已传送至打印机。在:%s'%now
        sound_path += 'printing.wav'
        sound.play(sound_path, winsound.SND_ALIAS)
        return message
    except Exception as e:
        f = open('d:/err_info.txt', 'a')
        f.writelines(str(datetime.datetime.now()))
        f.writelines(repr(e))
        f.writelines('\r\n')
        print(e.args)
        message = '打印传输未知错误。'
        sound_path += 'printing_failed.wav'
        sound.play(sound_path, winsound.SND_ALIAS)
        if xlBook:
            xlBook.Close(SaveChanges=0)
        return message
    finally:
        print('打印传输完毕')


# ws = workbook.active
# ws.print_area = 'A1:F10'  # 设置打印区域
# ws.print_options.horizontalCentered = True  # 水平居中
# ws.print_options.verticalCentered = True  # 垂直居中
# win32api.ShellExecute(0, "print", path, win32print.GetDefaultPrinter(), "", 0)


def get_data_from_excel(database_path, sheet_name):
    try:
        workbook = openpyxl.load_workbook(database_path)
        sheet = workbook[sheet_name]
        # max_row = sheet.max_row
        # area = 'A1:E' + str(max_row)
        # data = sheet[area]
        data = []

        for row in sheet.values:
            data.append(row)
        return data
    except Exception as e:
        f = open('d:/err_info.txt', 'a')
        f.writelines(str(datetime.datetime.now()))
        f.writelines(repr(e))
        f.writelines('\r\n')
        return ''

Auto_Print.py模块代码

from PyQt5.QtWidgets import QApplication, QMainWindow, QSystemTrayIcon, QMenu, QAction, qApp, QListWidget
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QPalette, QBrush, QPixmap
from PyQt5.QtCore import QSettings
from PyQt5.QtCore import QDate, Qt
from AutoPrintSystem import Ui_MainWindow
from pynput.keyboard import Key, Controller, Listener
import winsound, json, serial, re, time, icon_rc, os, threading, datetime, sys
import sound, data_handle, AutoPrintSystem

print_mode = '1'
banci = '0'
jihao = '0'
zubie = '0'

def settings():
    # 创建json配置文件
    settings_file_path = 'd:/settings.json'
    if os.path.exists(settings_file_path):
        settings_file = open(settings_file_path, 'r')
        mysettings = json.loads(settings_file.read())
        return mysettings
    else:
        mysettings = {
            "parent_access_path": "C:/Users/john/Desktop/Auto_Print/axl/AXL产品数据库-后端.accdb",
            "database_path": "C:/Users/john/Desktop/Auto_Print/database.xlsx",
            "product_info_path": "C:/Users/john/Desktop/Auto_Print/axl/QMS318吹膜式样书.mdb",
            "print_file_path": "C:/Users/john/Desktop/Auto_Print/print_file.xlsx",
            "sound_path": "C:/Users/john/Desktop/Auto_Print/提示音/",
            "PWD": "8110",
            "jilubiao_sheet_name": "吹膜记录表",
            "jilubiao_area": "B2:AT36",
            "rukudan_area": "A1:B7",
            "rukudan_sheet_name": "入库单",
            "all_jihao": ['28', '27', '25', '24', '23', '22', '21', '16','13','06', '04'],
            "dingdanhao_cell": (3, 20),
            "jihao_cell": (2, 26),
            "guanlibianhao_cell": (3, 6),
            "pinming_cell": (3, 12),
            "chicun_cell": (3, 28),
            "jizhunzhongliang_cell": (16, 7),
            "riqi_cell": (2, 12),
            "pihao_cell": (2, 4),
            "j_s_cell": (18, 7),
            "j_x_cell": (17, 7),
            "kuandu_cell": (16, 10),
            "k_s_cell": (18, 10),
            "k_x_cell": (17, 10),
            "tongkuan_cell": (16, 13),
            "t_s_cell": (18, 13),
            "t_x_cell": (17, 13),
            "juanchang_cell": (17, 15),
            "yuanfanzhongliang_cell": (16, 18),
            "y_s_cell": (18, 18),
            "y_x_cell": (17, 18),
            "zhishishu_cell": (4, 6),
            "banci_cell": (2, 19),  # 早晚
            "zubie_cell": (2, 23),  # 甲乙
            "rukudan_dingdanhao_cell": (2, 2),
            "rukudan_guanlibianhao_cell": (3, 2),
            "rukudan_pinming_cell": (4, 2),
            "rukudan_riqi_cell": (1, 2),
            "rukudan_pihao_cell": (6, 2)
        }
        context = json.dumps(mysettings, ensure_ascii=False)
        settings_file = open(settings_file_path, 'w')
        settings_file.write(context)
        settings_file.close()
        return mysettings


mysettings = settings()

database_path = mysettings['database_path']
parent_access_path = mysettings['parent_access_path']
print_file_path = mysettings['print_file_path']
product_info_path = mysettings['product_info_path']
jilubiao_sheet_name = mysettings['jilubiao_sheet_name']
jilubiao_area = mysettings['jilubiao_area']
rukudan_sheet_name = mysettings['rukudan_sheet_name']
rukudan_area = mysettings['rukudan_area']
PWD = mysettings['PWD']
all_jihao = mysettings['all_jihao']

sound_path = mysettings['sound_path']
dingdanhao_cell = mysettings["dingdanhao_cell"]
guanlibianhao_cell = mysettings["guanlibianhao_cell"]
pinming_cell = mysettings["pinming_cell"]
chicun_cell = mysettings["chicun_cell"]
jizhunzhongliang_cell = mysettings["jizhunzhongliang_cell"]
riqi_cell = mysettings["riqi_cell"]
jihao_cell = mysettings["jihao_cell"]
pihao_cell = mysettings["pihao_cell"]
j_s_cell = mysettings["j_s_cell"]
j_x_cell = mysettings["j_x_cell"]
kuandu_cell = mysettings["kuandu_cell"]
k_s_cell = mysettings["k_s_cell"]
k_x_cell = mysettings["k_x_cell"]
tongkuan_cell = mysettings["tongkuan_cell"]
t_s_cell = mysettings["t_s_cell"]
t_x_cell = mysettings["t_x_cell"]
juanchang_cell = mysettings["juanchang_cell"]
yuanfanzhongliang_cell = mysettings["yuanfanzhongliang_cell"]
y_s_cell = mysettings["y_s_cell"]
y_x_cell = mysettings["y_x_cell"]
zhishishu_cell = mysettings["zhishishu_cell"]
banci_cell = mysettings["banci_cell"]
zubie_cell = mysettings["zubie_cell"]
rukudan_dingdanhao_cell = mysettings['rukudan_dingdanhao_cell']
rukudan_guanlibianhao_cell = mysettings['rukudan_guanlibianhao_cell']
rukudan_pinming_cell = mysettings['rukudan_pinming_cell']
rukudan_riqi_cell = mysettings['rukudan_riqi_cell']
rukudan_pihao_cell = mysettings['rukudan_pihao_cell']


def get_today():
    current_time = datetime.datetime.now()
    today = [current_time.year, current_time.month, current_time.day, current_time.hour, current_time.minute]
    return today




# 继承Qmainwindow用于重写各种事件
class MainWindow(QMainWindow):
    def closeEvent(self, event):
        # 一键停止所有py进程
        os.system("taskkill /F /IM Auto_Print.exe")
        os.system("taskkill /F /IM Auto_Print_test.exe")

        os.system("taskkill /F /IM python.exe")
        print('窗口关闭事件生效')


class MyUi(Ui_MainWindow):

    def setupUi(self, MainWindow):
        super().setupUi(MainWindow)  # 很关键,没有这个获取不到继承的属性

        # 用于绑定menubar事件
        def get_data_from_menubar():
            message = data_handle.from_access_update_into_excel_xlsx(parent_access_path, product_info_path,
                                                                     database_path, PWD, sound_path)
            self.statusBar.showMessage(message)

        # 绑定menubar事件
        self.actionUpdate_database.triggered.connect(get_data_from_menubar)

        # 重写日期
        today = get_today()
        self.dateEdit.setDate(QDate.currentDate())

        # 重写窗口图标,需要将ico转为python
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(":/favicon.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        MainWindow.setWindowIcon(icon)

        # 重写listwidget
        def list_clicked(item):
            global jihao
            jihao = item.text()

        for jihao in all_jihao:
            self.listWidget.addItem(jihao)

        self.listWidget.itemClicked.connect(list_clicked)

        self.radioButton.setChecked(True)

        # 绑定radio事件
        def set_print_mode(btn):
            global print_mode
            if btn.text() == '记录表和入库单':
                if btn.isChecked() == True:
                    print_mode = '1'
                    print('mode1')
            if btn.text() == '仅记录表':
                if btn.isChecked() == True:
                    print_mode = '2'
                    print('mode2')
            if btn.text() == '仅入库单':
                if btn.isChecked() == True:
                    print_mode = '3'
                    print('mode3')

        self.radioButton.toggled.connect(lambda: set_print_mode(self.radioButton))
        self.radioButton_2.toggled.connect(lambda: set_print_mode(self.radioButton_2))
        self.radioButton_3.toggled.connect(lambda: set_print_mode(self.radioButton_3))

        # 绑定banci radio事件
        def set_banci(btn):
            global banci
            if btn.text() == '早':
                if btn.isChecked() == True:
                    banci = '1'
                    print('班次1')
            if btn.text() == '夜':
                if btn.isChecked() == True:
                    banci = '2'
                    print('班次2')

        self.radioButton_4.toggled.connect(lambda: set_banci(self.radioButton_4))
        self.radioButton_5.toggled.connect(lambda: set_banci(self.radioButton_5))

        def set_zubie(btn):
            global zubie
            if btn.text() == '甲':
                if btn.isChecked() == True:
                    zubie = '1'
                    print('甲班')
            if btn.text() == '乙':
                if btn.isChecked() == True:
                    zubie = '2'
                    print('乙班')

        self.radioButton_6.toggled.connect(lambda: set_zubie(self.radioButton_6))
        self.radioButton_7.toggled.connect(lambda: set_zubie(self.radioButton_7))

        # # 隐藏托盘功能
        # def tray_event(self):
        #     self.tray.show()
        #
        # self.tray = QSystemTrayIcon()
        # self.tray.setIcon(icon)
        # # 设置托盘点击事件函数
        # self.tray.activated.connect(tray_event)
        # # 创建菜单
        # tray_menu = QMenu(QApplication.desktop())
        # # 添加1级菜单动作选项,还原主窗口
        # self.RestoreAction = QAction(u'还原', self, triggered=MainWindow.show)
        # # 添加1级菜单动作选项退出主程序
        # self.QuitAction = QAction(u'退出', self, triggered=qApp.quit)
        # # 为菜单添加动作
        # self.tray_menu.addAction(self.RestoreAction)
        # self.tray_menu.addAction(self.QuitAction)
        # # 设置系统托盘菜单
        # self.tray.setContextMenu(self.tray_menu)

        # 改变标签背景
        # ui.label_3.setAutoFillBackground(True)
        # palette = QPalette()
        # palette.setColor(QPalette.Window, Qt.red)
        # ui.label_3.setPalette(palette)

        # 改变窗体颜色
        # palette = QPalette()
        # # palette.setColor(QPalette.Background, Qt.dark)
        # palette.setBrush(QPalette.Background,QBrush(QPixmap("back.PNG")))
        # mainWindow.setPalette(palette)


if __name__ == '__main__':
    # 启动声音
    start_sound_path = sound_path + 'start.wav'
    sound.play(start_sound_path, winsound.SND_ALIAS)

    # 定义应用
    app = QApplication(sys.argv)
    icon = QtGui.QIcon()
    icon.addPixmap(QtGui.QPixmap(":/favicon1.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)

    app.setWindowIcon(icon)
    # 实例化UI窗口
    ui = MyUi()


    # 从串口获取数据
    def send_from_serial_port():
        # scan_listener_sound_path = sound_path + 'scan_listener.wav'
        # sound.play(scan_listener_sound_path, winsound.SND_ALIAS)

        # 等待myui对象创建
        time.sleep(1)

        scan_val_line = ui.lineEdit
        dingdanhao_line = ui.lineEdit_7
        guanlibianhao_line = ui.lineEdit_2
        pinming_line = ui.lineEdit_5
        chicun_line = ui.lineEdit_6
        riqi_line = ui.dateEdit
        zhishishu_line = ui.lineEdit_40
        jizhunzhongliang_line = ui.lineEdit_3
        j_s_line = ui.lineEdit_4
        j_x_line = ui.lineEdit_8
        PE_hou_line = ui.lineEdit_41
        PE_s_line = ui.lineEdit_42
        PE_x_line = ui.lineEdit_43
        kuandu_line = ui.lineEdit_9
        k_s_line = ui.lineEdit_10
        k_x_line = ui.lineEdit_11
        tongkuan_line = ui.lineEdit_15
        t_s_line = ui.lineEdit_16
        t_x_line = ui.lineEdit_17
        juanchang_line = ui.lineEdit_18
        yuanfanzhongliang_line = ui.lineEdit_12
        y_s_line = ui.lineEdit_13
        y_x_line = ui.lineEdit_14

        def receive(ser):
            data = ''
            try:
                while ser.inWaiting() > 0:
                    data += ser.read().decode()
                return data
            except Exception as e:
                return data

        try:
            ser = serial.Serial("com3", 9600, timeout=0.5)
        except Exception as e:
            # 在D盘创建了一个错误日志,此处代码为写入错误日志。
            f = open('d:/err_info.txt', 'a')
            f.writelines(str(datetime.datetime.now()))
            f.writelines(repr(e))
            f.writelines('\r\n')

            f.close()
            ser = ''
            com3_not_found_sound_path = sound_path + 'COM3_not_found.wav'
            sound.play(com3_not_found_sound_path, winsound.SND_ALIAS)
            print(e.args)
            mainWindow.close()

        while True:
            scan_val = receive(ser)
            if scan_val != '':
                # scan_val = '123456|YJJ001-16|10.09'
                if re.match('.+[|].+[|].+', scan_val):
                    print('扫描到数据:%s' % scan_val)

                    dingdanhao_line.clear()
                    guanlibianhao_line.clear()
                    pinming_line.clear()
                    chicun_line.clear()
                    scan_val_line.clear()

                    zhishishu_line.clear()
                    jizhunzhongliang_line.clear()
                    j_s_line.clear()
                    j_x_line.clear()
                    PE_hou_line.clear()
                    PE_s_line.clear()
                    PE_x_line.clear()
                    kuandu_line.clear()
                    k_s_line.clear()
                    k_x_line.clear()
                    tongkuan_line.clear()
                    t_s_line.clear()
                    t_x_line.clear()
                    juanchang_line.clear()
                    yuanfanzhongliang_line.clear()
                    y_s_line.clear()
                    y_x_line.clear()

                    print('窗口清理完毕')

                    scan_val_line.setText(scan_val)
                    arr = scan_val.split('|')
                    dingdanhao = arr[0]
                    dingdanhao_line.setText(dingdanhao)
                    guanlibianhao = arr[1]
                    guanlibianhao_line.setText(guanlibianhao)
                    zhishishu = float(arr[2])
                    xiaoshu = zhishishu - int(zhishishu)
                    if xiaoshu > 0.09:
                        zhishishu = int(zhishishu) + 1
                    else:
                        zhishishu = int(zhishishu)
                    zhishishu_line.setText(str(zhishishu))

                    print('获取到初步信息')

                    # 获取管理编号对应的产品信息赋给窗体
                    data = data_handle.get_data_from_excel(database_path, 'data')
                    found = 0
                    for d in data:
                        if d[1] == guanlibianhao:
                            found = 1
                            pinming = d[2]
                            chicun = d[3]
                            jizhunzhongliang = round(float(d[4]), 2) if d[4] is not None else 0
                            j_x = round(float(d[5]), 2) if d[5] is not None else 0
                            j_s = round(float(d[6]), 2) if d[6] is not None else 0
                            PE_hou = round(float(d[7]), 2) if d[7] is not None else 0
                            PE_x = round(float(d[8]), 3) if d[8] is not None else 0
                            PE_s = round(float(d[9]), 3) if d[9] is not None else 0
                            kuandu = float(d[10]) if d[10] is not None else 0
                            k_x = round(float(d[11]), 2) if d[11] is not None else 0
                            k_s = round(float(d[12]), 2) if d[12] is not None else 0
                            tongkuan = float(d[13]) if d[13] is not None else 0
                            juanchang = float(d[14]) / 1000 if d[14] is not None else 0
                            yuanfanzhongliang = round(float(d[15]), 2) if d[15] is not None else 0
                            y_s = round(float(d[16]), 2) if d[16] is not None else 0
                            y_x = round(float(d[17]), 2) if d[17] is not None else 0

                            pinming_line.setText(pinming)
                            chicun_line.setText(chicun)
                            jizhunzhongliang_line.setText(str(jizhunzhongliang))
                            j_s_line.setText(str(j_s))
                            j_x_line.setText(str(j_x))
                            PE_hou_line.setText(str(PE_hou))
                            PE_s_line.setText(str(PE_s))
                            PE_x_line.setText(str(PE_x))
                            kuandu_line.setText(str(kuandu))
                            k_s_line.setText(str(k_s))
                            k_x_line.setText(str(k_x))
                            tongkuan_line.setText(str(tongkuan))
                            t_s = round(float(tongkuan), 2) * 1.03
                            t_x = round(float(tongkuan), 2) * 0.98
                            t_s_line.setText(str(t_s))
                            t_x_line.setText(str(t_x))

                            juanchang_line.setText(str(juanchang))
                            yuanfanzhongliang_line.setText(str(yuanfanzhongliang))
                            y_s_line.setText(str(y_s))
                            y_x_line.setText(str(y_x))

                            print('窗体内容添加完毕')

                            today = ui.dateEdit.date().toPyDate()
                            global jihao

                            if (banci == '0') or (jihao == '0') or (zubie == '0'):
                                scan_listener_sound_path = sound_path + 'banci_or_jihao_not_selected.wav'
                                sound.play(scan_listener_sound_path, winsound.SND_ALIAS)
                                continue
                            else:
                                pihao = today.strftime('%Y%m%d')[2:] + banci + jihao
                            print(pihao)
                            today = today.strftime('%Y/%m/%d')

                            # 判断是防锈还是PE
                            if re.match('YJJ.*?|YHJ.*', guanlibianhao):
                                print('PE')
                                jizhunzhongliang = PE_hou
                                j_s = PE_s
                                j_x = PE_x

                            lis_jilubiao = [
                                [dingdanhao_cell, dingdanhao],
                                [jihao_cell, jihao],
                                [guanlibianhao_cell, guanlibianhao],
                                [pinming_cell, pinming],
                                [chicun_cell, chicun],
                                [jizhunzhongliang_cell, jizhunzhongliang],
                                [riqi_cell, today],
                                [pihao_cell, pihao],
                                [j_s_cell, j_s],
                                [j_x_cell, j_x],
                                [kuandu_cell, kuandu],
                                [k_s_cell, k_s],
                                [k_x_cell, k_x],
                                [tongkuan_cell, tongkuan],
                                [t_s_cell, t_s],
                                [t_x_cell, t_x],
                                [juanchang_cell, juanchang],
                                [yuanfanzhongliang_cell, yuanfanzhongliang],
                                [y_s_cell, y_s],
                                [y_x_cell, y_x],
                                [zhishishu_cell, zhishishu],
                                [banci_cell, "早" if banci == '1' else "夜"],
                                [zubie_cell,"甲" if zubie == '1' else "乙"]

                            ]

                            lis_rukudan = [
                                [rukudan_dingdanhao_cell, dingdanhao],
                                [rukudan_guanlibianhao_cell, guanlibianhao],
                                [rukudan_pinming_cell, pinming],
                                [rukudan_riqi_cell, today],
                                [rukudan_pihao_cell, pihao]

                            ]

                            message = data_handle.scan_val_to_excel(print_file_path, jilubiao_sheet_name, jilubiao_area,
                                                                    rukudan_sheet_name, rukudan_area, lis_jilubiao,
                                                                    lis_rukudan,
                                                                    sound_path, print_mode)
                            jihao = '0'
                            ui.listWidget.clearSelection()

                            ui.statusBar.showMessage(message)

                            break

                    if found != 1:
                        ui.statusBar.showMessage('未找到此产品!')
                        scan_listener_sound_path = sound_path + 'not_found.wav'
                        sound.play(scan_listener_sound_path, winsound.SND_ALIAS)
                    print('本次扫描结束')
                else:
                    scan_val_line.setText(scan_val)
                    scan_failed = sound_path + 'scan_failed.wav'
                    sound.play(scan_failed, winsound.SND_ALIAS)

            time.sleep(0.1)


    # 开启监听线程
    thread = threading.Thread(target=send_from_serial_port, name='port_listener')
    print('下面开始线程')
    thread.start()

    # 将Qt5的窗口内容传递进来
    mainWindow = MainWindow()
    ui.setupUi(mainWindow)

    # 更新数据库
    upadate_database_result = data_handle.from_access_update_into_excel_xlsx(parent_access_path, product_info_path,
                                                                             database_path, PWD, sound_path)
    ui.statusBar.showMessage(upadate_database_result)

    mainWindow.show()
    ready_sound_path = sound_path + 'ready.wav'
    sound.play(ready_sound_path, winsound.SND_ALIAS)

    sys.exit(app.exec_())

D盘中放入settings.json配置文件

{"parent_access_path": "C:/Users/john/Desktop/Auto_Print/axl/AXL产品数据库-后端.accdb", "database_path": "C:/Users/john/Desktop/Auto_Print/database.xlsx", "product_info_path": "C:/Users/john/Desktop/Auto_Print/axl/QMS318吹膜式样书.mdb", "print_file_path": "C:/Users/john/Desktop/Auto_Print/print_file.xlsx", "sound_path": "C:/Users/john/Desktop/Auto_Print/提示音/", "PWD": "8110", "jilubiao_sheet_name": "吹膜记录表", "jilubiao_area": "B2:AT36", "rukudan_area": "A1:B7", "rukudan_sheet_name": "入库单", "all_jihao": ["28", "27", "25", "24", "23", "22", "21", "16", "13", "06", "04"], "dingdanhao_cell": [3, 20], "jihao_cell": [2, 26], "guanlibianhao_cell": [3, 6], "pinming_cell": [3, 12], "chicun_cell": [3, 28], "jizhunzhongliang_cell": [16, 7], "riqi_cell": [2, 12], "pihao_cell": [2, 4], "j_s_cell": [18, 7], "j_x_cell": [17, 7], "kuandu_cell": [16, 10], "k_s_cell": [18, 10], "k_x_cell": [17, 10], "tongkuan_cell": [16, 13], "t_s_cell": [18, 13], "t_x_cell": [17, 13], "juanchang_cell": [17, 15], "yuanfanzhongliang_cell": [16, 18], "y_s_cell": [18, 18], "y_x_cell": [17, 18], "zhishishu_cell": [4, 6], "banci_cell": [2, 19], "zubie_cell": [2, 23], "rukudan_dingdanhao_cell": [2, 2], "rukudan_guanlibianhao_cell": [3, 2], "rukudan_pinming_cell": [4, 2], "rukudan_riqi_cell": [1, 2], "rukudan_pihao_cell": [6, 2]}
  • 6
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 学生宿舍管理系统是基于Python、PyQt5和MySQL开发的一个项目,旨在帮助学校高效管理学生宿舍的入住、退宿、维修等信息。下面是该项目的详细说明文档: 1. 系统功能 - 学生宿舍的入住管理:可以添加、删除、修改学生的宿舍信息,包括姓名、学号、宿舍楼号、宿舍号等内容。 - 学生宿舍的维修管理:可以记录宿舍的维修情况,包括宿舍号、维修日期、维修原因等信息,并能够查看历史维修记录。 - 学生宿舍的退宿管理:可以退宿学生,并更新宿舍的入住状态。 - 学生宿舍的查询功能:可以通过学号、宿舍楼号、宿舍号等信息,查询学生宿舍的相关信息。 2. 系统架构 - 前端界面使用PyQt5实现,包括各个功能模块的界面设计。 - 后端数据存储使用MySQL数据库,存储学生宿舍的相关信息。 - Python作为开发语言,通过PyQt5库提供的方法与MySQL数据库进行交互。 3. 系统运行环境 - 操作系统:推荐使用Windows系统,也可以在Linux或Mac OS上运行。 - Python版本:推荐Python3.x版本。 - PyQt5安装:使用pip命令安装PyQt5库,pip install pyqt5。 - MySQL安装:安装MySQL数据库,并创建对应的数据库和表。 4. 运行方式 - 下载源码:从GitHub或其他源码托管平台下载学生宿舍管理系统的源码。 - 配置数据库:在源码修改连接数据库的相关信息,包括MySQL的地址、用户名、密码等。 - 运行程序:通过Python命令运行主程序文件,即可启动系统界面。 - 页面操作:根据界面提供的按钮和输入框进行相应的添加、修改、删除、查询等操作。 5. 注意事项 - 由于本项目是基于Python和PyQt5开发的,需要对Python和GUI界面开发有一定的了解。 - 在使用该系统之前,需要创建对应的数据库和表,并将相关信息配置到源码。 - 可以根据实际需要进行功能的扩展和修改,例如增加宿舍楼管理、学生信息管理等模块。 这个学生宿舍管理系统源码提供了一个简单易用的GUI界面,方便学校管理学生宿舍的各项信息,并且可以快速查询和统计宿舍相关数据,帮助学校实现宿舍管理的自动化和规范化。 ### 回答2: 学生宿舍管理系统是基于Python、PyQt5和MySQL实现的一款图形用户界面(GUI)应用程序。该系统旨在帮助学校管理学生宿舍的入住、退房和维护等事务。 系统的数据库设计如下: 1. 学生表(Student):包含学生的基本信息,如学号、姓名、性别、年龄等。 2. 宿舍楼表(DormitoryBuilding):记录宿舍楼的信息,如楼号、楼层数、可容纳人数等。 3. 宿舍房间表(DormitoryRoom):每个宿舍楼内包括多个宿舍房间,该表记录了宿舍房间的编号、所在楼号、可容纳人数等。 4. 入住记录表(CheckInRecord):记录学生的入住情况,包括入住日期、房间号、学生信息等。 系统的功能模块如下: 1. 学生管理:可以对学生的基本信息进行增加、删除、修改和查询操作。 2. 宿舍楼管理:可以对宿舍楼的信息进行增加、删除、修改和查询操作。 3. 宿舍房间管理:可以对宿舍房间的信息进行增加、删除、修改和查询操作。 4. 入住管理:可以对学生的入住情况进行登记、查询和退房操作。 5. 统计功能:可以统计宿舍楼的入住情况和宿舍房间的入住率。 系统的GUI界面采用PyQt5库进行开发,具有用户友好的操作界面,方便用户进行操作和管理。 总结起来,该学生宿舍管理系统使用Python编程语言、PyQt5图形界面库和MySQL数据库实现了学生、宿舍楼、宿舍房间和入住记录的管理功能,方便学校对学生宿舍的管理和维护。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值