PyQt多窗口应用开发:构建完整的可二次开发用户登录注册模板

一、引言

在当代Python GUI开发领域,PyQt框架凭借其与Qt库的深度整合,已成为构建复杂桌面应用的首选方案之一。本模板针对用户认证场景中的多窗口协同问题构建了一套基础可拓展的解决方案,将离散的登录、注册、主页三大功能模块,通过精心设计的信号-槽机制整合为完整的用户登录注册标准化架构,方便开发者能够快速移植到不同领域的应用场景中去

二、GUI界面设计

使用PyQt5进行界面的搭建,登录(普通用户和管理员)、主页和注册(单个注册和批量注册)界面分别如下:

1.效果演示

2.登录界面

登录界面含有两个标签页,分别是"普通用户"和"管理员"页面。这两个页面的整体布局和控件一致,均需输入用户名和密码才可以正常登录,而且在最下方均含有"退出系统"的按钮,可以随时直接退出系统。

注意:两(多)个标签页 的构造需要用到Tab Widget控件,其位置如下,找到后直接拖入对应Form即可:

拖入后,默认标签有两个,分别是Tab 1和Tab 2,需要将其分别重命名为"普通用户"和"管理员"。单击选中当前Tab Widget,在"属性编辑器"中找到"currentTabText",单击"Tab 1"可将其修改为"普通用户",Tab 2也是同理。

其余控件的添加比较简单,这里就不多赘述,通过pyuic5产生的GUI界面代码UI_Login.py如下:

python 复制代码
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'UI_Login.ui'
#
# Created by: PyQt5 UI code generator 5.15.11
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Login(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.setEnabled(True)
        Form.resize(300, 420)
        Form.setMinimumSize(QtCore.QSize(300, 420))
        Form.setMaximumSize(QtCore.QSize(300, 420))
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(":/image1.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        Form.setWindowIcon(icon)
        self.label_5 = QtWidgets.QLabel(Form)
        self.label_5.setGeometry(QtCore.QRect(130, 60, 141, 31))
        font = QtGui.QFont()
        font.setFamily("字魂181号-飞驰标题体")
        font.setPointSize(16)
        self.label_5.setFont(font)
        self.label_5.setObjectName("label_5")
        self.label_8 = QtWidgets.QLabel(Form)
        self.label_8.setGeometry(QtCore.QRect(70, 10, 201, 31))
        font = QtGui.QFont()
        font.setFamily("字魂181号-飞驰标题体")
        font.setPointSize(24)
        font.setBold(False)
        font.setWeight(50)
        self.label_8.setFont(font)
        self.label_8.setObjectName("label_8")
        self.label_10 = QtWidgets.QLabel(Form)
        self.label_10.setGeometry(QtCore.QRect(240, 50, 71, 51))
        self.label_10.setText("")
        self.label_10.setPixmap(QtGui.QPixmap(":/image1.png"))
        self.label_10.setObjectName("label_10")
        self.tabWidget = QtWidgets.QTabWidget(Form)
        self.tabWidget.setGeometry(QtCore.QRect(30, 120, 241, 231))
        self.tabWidget.setObjectName("tabWidget")
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.label = QtWidgets.QLabel(self.tab)
        self.label.setGeometry(QtCore.QRect(30, 71, 54, 21))
        font = QtGui.QFont()
        font.setFamily("Adobe Arabic")
        font.setPointSize(12)
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.tab)
        self.label_2.setGeometry(QtCore.QRect(30, 110, 54, 21))
        font = QtGui.QFont()
        font.setFamily("Adobe Arabic")
        font.setPointSize(12)
        self.label_2.setFont(font)
        self.label_2.setObjectName("label_2")
        self.lineEdit = QtWidgets.QLineEdit(self.tab)
        self.lineEdit.setGeometry(QtCore.QRect(100, 70, 113, 20))
        self.lineEdit.setObjectName("lineEdit")
        self.lineEdit_2 = QtWidgets.QLineEdit(self.tab)
        self.lineEdit_2.setGeometry(QtCore.QRect(100, 110, 113, 20))
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.pushButton = QtWidgets.QPushButton(self.tab)
        self.pushButton.setGeometry(QtCore.QRect(30, 160, 181, 23))
        self.pushButton.setObjectName("pushButton")
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.label_3 = QtWidgets.QLabel(self.tab_2)
        self.label_3.setGeometry(QtCore.QRect(30, 110, 54, 21))
        font = QtGui.QFont()
        font.setFamily("Adobe Arabic")
        font.setPointSize(12)
        self.label_3.setFont(font)
        self.label_3.setObjectName("label_3")
        self.lineEdit_3 = QtWidgets.QLineEdit(self.tab_2)
        self.lineEdit_3.setGeometry(QtCore.QRect(100, 110, 113, 20))
        self.lineEdit_3.setInputMethodHints(QtCore.Qt.ImhNone)
        self.lineEdit_3.setObjectName("lineEdit_3")
        self.lineEdit_4 = QtWidgets.QLineEdit(self.tab_2)
        self.lineEdit_4.setGeometry(QtCore.QRect(100, 70, 113, 20))
        self.lineEdit_4.setObjectName("lineEdit_4")
        self.label_4 = QtWidgets.QLabel(self.tab_2)
        self.label_4.setGeometry(QtCore.QRect(30, 71, 54, 21))
        font = QtGui.QFont()
        font.setFamily("Adobe Arabic")
        font.setPointSize(12)
        self.label_4.setFont(font)
        self.label_4.setObjectName("label_4")
        self.pushButton_2 = QtWidgets.QPushButton(self.tab_2)
        self.pushButton_2.setGeometry(QtCore.QRect(30, 160, 181, 23))
        self.pushButton_2.setObjectName("pushButton_2")
        self.tabWidget.addTab(self.tab_2, "")
        self.pushButton_3 = QtWidgets.QPushButton(Form)
        self.pushButton_3.setGeometry(QtCore.QRect(60, 370, 181, 23))
        self.pushButton_3.setObjectName("pushButton_3")

        self.retranslateUi(Form)
        self.tabWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Login"))
        self.label_5.setText(_translate("Form", "Designed By"))
        self.label_8.setText(_translate("Form", "Login-Page"))
        self.label.setText(_translate("Form", "用户名"))
        self.label_2.setText(_translate("Form", "密      码"))
        self.pushButton.setText(_translate("Form", "登录系统"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("Form", "普通用户"))
        self.label_3.setText(_translate("Form", "密      码"))
        self.label_4.setText(_translate("Form", "用户名"))
        self.pushButton_2.setText(_translate("Form", "登录系统"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("Form", "管理员"))
        self.pushButton_3.setText(_translate("Form", "退出系统"))
import ziyuan_rc

这里需要补充一点,通过QtDesigner设计出的.ui文件,再经pyuic转为.py文件后统一默认的类名称是Ui_Form。而本项目要实现多窗口间的跳转,则需要多个.ui界面文件,其对应的类名称不应该均是Ui_Form,需要在pyuic转换后,手动更改名称,便于区别(如本项目中登录界面为Login,主页界面为Welcome,注册界面为Register)。

3.主页界面

因本项目仅给出登录/注册与主页间的跳转架构,故主页界面设计比较简单,未加入相应的功能,有需求的可在此基础上进行二次开发。通过pyuic5产生的GUI界面代码UI_Welcome.py如下:

python 复制代码
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'UI_Welcome.ui'
#
# Created by: PyQt5 UI code generator 5.15.11
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Welcome(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(300, 420)
        Form.setMinimumSize(QtCore.QSize(300, 420))
        Form.setMaximumSize(QtCore.QSize(300, 420))
        self.label_11 = QtWidgets.QLabel(Form)
        self.label_11.setGeometry(QtCore.QRect(240, 50, 71, 51))
        self.label_11.setText("")
        self.label_11.setPixmap(QtGui.QPixmap(":/image1.png"))
        self.label_11.setObjectName("label_11")
        self.label_9 = QtWidgets.QLabel(Form)
        self.label_9.setGeometry(QtCore.QRect(50, 10, 221, 31))
        font = QtGui.QFont()
        font.setFamily("字魂181号-飞驰标题体")
        font.setPointSize(24)
        font.setBold(False)
        font.setWeight(50)
        self.label_9.setFont(font)
        self.label_9.setObjectName("label_9")
        self.label_6 = QtWidgets.QLabel(Form)
        self.label_6.setGeometry(QtCore.QRect(130, 60, 141, 31))
        font = QtGui.QFont()
        font.setFamily("字魂181号-飞驰标题体")
        font.setPointSize(16)
        self.label_6.setFont(font)
        self.label_6.setObjectName("label_6")
        self.label = QtWidgets.QLabel(Form)
        self.label.setGeometry(QtCore.QRect(40, 120, 251, 141))
        font = QtGui.QFont()
        font.setFamily("字魂181号-飞驰标题体")
        font.setPointSize(39)
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.pushButton_2 = QtWidgets.QPushButton(Form)
        self.pushButton_2.setGeometry(QtCore.QRect(110, 270, 81, 23))
        self.pushButton_2.setObjectName("pushButton_2")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Welcome"))
        self.label_9.setText(_translate("Form", "Welcome-Page"))
        self.label_6.setText(_translate("Form", "Designed By"))
        self.label.setText(_translate("Form", "欢迎进入!"))
        self.pushButton_2.setText(_translate("Form", "返回登录界面"))
import ziyuan_rc

4.注册界面

注册界面与登录界面基本一致,唯一与登录界面不同的是,注册界面中的"登录"按钮变成了"注册",最终实现管理员添加普通用户的功能(可单个注册新用户,也可批量注册新用户)。通过pyuic5产生的GUI界面代码UI_Welcome.py如下:

python 复制代码
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'UI_Register.ui'
#
# Created by: PyQt5 UI code generator 5.15.11
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Register(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(300, 420)
        Form.setMinimumSize(QtCore.QSize(300, 420))
        Form.setMaximumSize(QtCore.QSize(300, 420))
        self.label_6 = QtWidgets.QLabel(Form)
        self.label_6.setGeometry(QtCore.QRect(120, 60, 141, 31))
        font = QtGui.QFont()
        font.setFamily("字魂181号-飞驰标题体")
        font.setPointSize(16)
        self.label_6.setFont(font)
        self.label_6.setObjectName("label_6")
        self.label_9 = QtWidgets.QLabel(Form)
        self.label_9.setGeometry(QtCore.QRect(40, 10, 221, 31))
        font = QtGui.QFont()
        font.setFamily("字魂181号-飞驰标题体")
        font.setPointSize(24)
        font.setBold(False)
        font.setWeight(50)
        self.label_9.setFont(font)
        self.label_9.setObjectName("label_9")
        self.label_11 = QtWidgets.QLabel(Form)
        self.label_11.setGeometry(QtCore.QRect(230, 50, 71, 51))
        self.label_11.setText("")
        self.label_11.setPixmap(QtGui.QPixmap(":/image1.png"))
        self.label_11.setObjectName("label_11")
        self.pushButton_2 = QtWidgets.QPushButton(Form)
        self.pushButton_2.setGeometry(QtCore.QRect(90, 350, 131, 23))
        self.pushButton_2.setObjectName("pushButton_2")
        self.tabWidget = QtWidgets.QTabWidget(Form)
        self.tabWidget.setGeometry(QtCore.QRect(40, 140, 231, 181))
        self.tabWidget.setObjectName("tabWidget")
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.label_2 = QtWidgets.QLabel(self.tab)
        self.label_2.setGeometry(QtCore.QRect(20, 70, 54, 21))
        font = QtGui.QFont()
        font.setFamily("Adobe Arabic")
        font.setPointSize(12)
        self.label_2.setFont(font)
        self.label_2.setObjectName("label_2")
        self.label = QtWidgets.QLabel(self.tab)
        self.label.setGeometry(QtCore.QRect(20, 31, 54, 21))
        font = QtGui.QFont()
        font.setFamily("Adobe Arabic")
        font.setPointSize(12)
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.lineEdit = QtWidgets.QLineEdit(self.tab)
        self.lineEdit.setGeometry(QtCore.QRect(100, 30, 113, 20))
        self.lineEdit.setObjectName("lineEdit")
        self.lineEdit_2 = QtWidgets.QLineEdit(self.tab)
        self.lineEdit_2.setGeometry(QtCore.QRect(100, 70, 113, 20))
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.pushButton = QtWidgets.QPushButton(self.tab)
        self.pushButton.setGeometry(QtCore.QRect(100, 110, 111, 23))
        self.pushButton.setObjectName("pushButton")
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.pushButton_3 = QtWidgets.QPushButton(self.tab_2)
        self.pushButton_3.setGeometry(QtCore.QRect(50, 20, 131, 23))
        self.pushButton_3.setObjectName("pushButton_3")
        self.pushButton_4 = QtWidgets.QPushButton(self.tab_2)
        self.pushButton_4.setGeometry(QtCore.QRect(50, 70, 131, 23))
        self.pushButton_4.setObjectName("pushButton_4")
        self.pushButton_5 = QtWidgets.QPushButton(self.tab_2)
        self.pushButton_5.setGeometry(QtCore.QRect(50, 120, 131, 23))
        self.pushButton_5.setObjectName("pushButton_5")
        self.tabWidget.addTab(self.tab_2, "")
        self.tabWidget.raise_()
        self.label_6.raise_()
        self.label_9.raise_()
        self.label_11.raise_()
        self.pushButton_2.raise_()

        self.retranslateUi(Form)
        self.tabWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Register"))
        self.label_6.setText(_translate("Form", "Designed By"))
        self.label_9.setText(_translate("Form", "Register-Page"))
        self.pushButton_2.setText(_translate("Form", "返回登录界面"))
        self.label_2.setText(_translate("Form", "密      码"))
        self.label.setText(_translate("Form", "用户名"))
        self.pushButton.setText(_translate("Form", "注册"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("Form", "单个注册"))
        self.pushButton_3.setText(_translate("Form", "一、下载信息模板"))
        self.pushButton_4.setText(_translate("Form", "二、上传信息模板"))
        self.pushButton_5.setText(_translate("Form", "三、批量注册"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("Form", "批量注册"))
import ziyuan_rc

5.相关提示

上图分别对应普通用户登录成功、管理员登录成功、管理员注册单个普通用户成功、管理员批量注册普通用户成功、从主页返回以及退出整体系统的相应提示。

三、主要程序详解

1.项目框架

UI文件夹中存放UI设计文件.ui和通过pyuic生成的对应.py文件,image1.png为图标文件,login_model.py为主程序,pyrcc将ziyuan.qrc资源文件转换为ziyuan_rc.py文件。

2.导入及全局变量设置

python 复制代码
import sys
from UI.UI_Login import *
from UI.UI_Welcome import *
from UI.UI_Register import *
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit
from openpyxl import Workbook
import pandas as pd
# 保持窗口大小和qtdesigner中的一致
from PyQt5 import QtCore
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)

yonghu = ['ceshi']
mima = ['ceshi']
gl_name = "admin"
gl_password = "admin"

导入三个前端页面设计文件:UI_Login.py、UI_Register.py和UI_Welcome.py时,需要注意他们在UI文件夹中,所以导入方式变为fom UI.UI_XXX impot *不懂为啥需要导入Qtcore的,请看************************************************************一键曝光:Python+PyQt实现的文件目录透视镜************************************************************

yonghu列表用于存储用户名,mima列表用于存储密码并与yonghu一一对应。 一般情况下,一个系统仅有一个管理员,所以在此可以直接定义变量(管理员账号和对应密码)方式来创建管理员。管理员只设置一个,用户名和密码均是"admin"。

3.loginpage类

(1)初始化设置

如下,主要将button绑定于对应的不同方法。

python 复制代码
class loginpage(QWidget, Login):
    def __init__(self):
        super(QWidget, self).__init__()
        self.setupUi(self)

        self.pushButton.clicked.connect(self.ToWelcome)
        self.pushButton_3.clicked.connect(self.tuichu)
        self.pushButton_2.clicked.connect(self.ToRegister)

        # self.lineEdit_3.setEchoMode(QLineEdit.Password) # 设置为密码掩码字符
        # self.lineEdit_2.setEchoMode(QLineEdit.Password)

如果有需要,**可通过最后两行将对应的lineedit设置为密码掩码字符,**效果如下。

(2)用户跳转到主页

python 复制代码
    def ToWelcome(self):
        yh_name = self.lineEdit.text()
        yh_mima = self.lineEdit_2.text()
        if yh_name != "":
            if yh_mima != "":
                if yh_name in yonghu:
                    if mima[yonghu.index(yh_name)] == yh_mima:
                        QtWidgets.QMessageBox.information(self, "成功", "欢迎用户!")
                        self.w_welcome = welcomepage()
                        self.w_welcome.show()
                        self.close()
                    else:
                        QtWidgets.QMessageBox.critical(self, "失败", "密码错误!")
                else:
                    QtWidgets.QMessageBox.critical(self, "失败", "用户不存在!")
            else:
                QtWidgets.QMessageBox.information(self, "提示", "请输入密码!")
        else:
            QtWidgets.QMessageBox.information(self, "提示", "请输入用户名!")

这里给出最为简单的用户验证机制:以if语句的嵌套在列表中判断用户名和密码的正确性,最终实现登录效果(当然也可以连接数据库)。值得注意的是,当用户身份验证正确后,需要实例化welcomepage页面,显示主页的同时,关闭登录页面。

(3)管理员跳转到注册页

python 复制代码
    def ToRegister(self):
        if self.lineEdit_4.text() != "":
            if self.lineEdit_3.text() != "":
                if self.lineEdit_4.text() == gl_name:
                    if self.lineEdit_3.text() == gl_password:
                        QtWidgets.QMessageBox.information(self, "成功", "欢迎管理员!")
                        self.w_register = registerpage()
                        self.w_register.show()
                        self.close()
                    else:
                        QtWidgets.QMessageBox.critical(self, "失败", "密码错误!")
                else:
                    QtWidgets.QMessageBox.critical(self, "失败", "用户不存在!")
            else:
                QtWidgets.QMessageBox.information(self, "提示", "请输入密码!")
        else:
            QtWidgets.QMessageBox.information(self, "提示", "请输入用户名!")

将用户输入的账号(lineedit_4)和密码(lineedit_3)与gl_name和gl_password分别对比核验,只有都相等时,才可以进入管理页面,否则给出对应提示。

(4)退出系统

python 复制代码
    def tuichu(self):
        QtWidgets.QMessageBox.information(self, "提示", "感谢使用!")
        self.close()

通过QMessageBox标准化反馈体系,构建符合人机工程学的提示流程。

4.welcompage类

结构框架类似于loginpage类,这里不详解。

python 复制代码
class welcomepage(QWidget, Welcome):
    def __init__(self):
        super(QWidget, self).__init__()
        self.setupUi(self)

        self.pushButton_2.clicked.connect(self.ToLogin)

    def ToLogin(self):
        QtWidgets.QMessageBox.information(self, "提示", "返回登录!")
        self.w_login = loginpage()
        self.w_login.show()
        self.close()

5.registerpage类

(1)初始化设置

python 复制代码
class registerpage(QWidget, Register):
    def __init__(self):
        super(QWidget, self).__init__()
        self.setupUi(self)

        self.pushButton_2.clicked.connect(self.ToLogin)
        self.pushButton.clicked.connect(self.zhucue)
        self.pushButton_3.clicked.connect(self.xiazai)
        self.pushButton_4.clicked.connect(self.shangchuan_df)
        self.pushButton_5.clicked.connect(self.piliang)

        self.shangchuan_flag = False

将相关button连接到相应函数,shangchuan_flag初步设置为false状态(用于标识是否上传文件)。

(2)管理员返回主页

python 复制代码
    def ToLogin(self):
        welcomepage.ToLogin(self)

需要说明一点:因主页和注册页均有返回登录页的按钮,因此这里的ToLogin方法不再重写,而是直接调用类welcomepage中的ToLogin方法。

(3)注册单个用户

python 复制代码
    def zhucue(self):
        dai_name = self.lineEdit.text()
        dai_mima = self.lineEdit_2.text()
        if dai_name != "":
            if dai_mima != "":
                if dai_name in yonghu:
                    QtWidgets.QMessageBox.information(self, "提示", "用户已存在,请勿重复注册!")
                else:
                    yonghu.append(dai_name)
                    mima.append(dai_mima)
                    QtWidgets.QMessageBox.information(self, "成功", "注册成功!")
            else:
                QtWidgets.QMessageBox.information(self, "提示", "请输入密码!")
        else:
            QtWidgets.QMessageBox.information(self, "提示", "请输入用户名!")

先判断待注册的用户是否已经存在,不存在时通过append()方法添加至列表中,否则提示。

(4)批量注册用户

python 复制代码
    def xiazai(self):
        # 设置并下载对应表模板文件
        wb = Workbook()
        ws = wb.active
        ws.column_dimensions['A'].width = 10
        ws.column_dimensions['B'].width = 10
        ws.cell(row=1, column=1, value="用户名")
        ws.cell(row=1, column=2, value="密码")
        wb.save('用户信息模板.xlsx')
        QtWidgets.QMessageBox.information(self, "成功", "用户信息模板下载成功,请查看当前目录!")

    def shangchuan_df(self):
        self.df = shangchuan()
        self.shangchuan_flag = True

    def piliang(self):
        if self.shangchuan_flag == True:
            for col in self.df.columns:
                for row in range(len(self.df)):
                    if col == '用户名':
                        yonghu.append(str(self.df.at[row, col]))
                    if col == '密码':
                        mima.append(str(self.df.at[row, col]))
            QtWidgets.QMessageBox.information(self, '成功', '批量注册成功!')
        else:
            QtWidgets.QMessageBox.critical(self, '提示', '请上传用户信息模板文件!')

先对用户信息模板文件的列宽、列名及文件名称进行设定;使用QMessageBox提示上传成功;接着调用自定义函数shangchuan()完成文件的选择与上传;最后遍历模板文件中的用户名与密码,并将其append()至yonghe和mimi中。自定义函数shangchuan()如下:

python 复制代码
def shangchuan():
    filepath, _ = QtWidgets.QFileDialog.getOpenFileName(None, "请选择用户信息模板", "", "XLSX工作表 (*.xlsx)")  # 获取文件路径
    if filepath:
        # 获取原始df
        yuanshi_df = pd.read_excel(filepath)
        if not yuanshi_df.empty:
            QtWidgets.QMessageBox.information(None, "成功", "用户信息模板上传成功!")
            return yuanshi_df
        else:
            QtWidgets.QMessageBox.critical(None, "提示", "请检查操作步骤或模板文件!")
    else:
        QtWidgets.QMessageBox.critical(None, "提示", "请选择XLSX工作表类型!")

四、总程序代码

说明:这里将三个类:loginpage、welcompage、registerpage均放置在同一.py中,实际上,最优解应该将其分别放置在三个.py中,便于后期在此基础之上进行继续开发

python 复制代码
import sys
from UI.UI_Login import *
from UI.UI_Welcome import *
from UI.UI_Register import *
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit
from openpyxl import Workbook
import pandas as pd
# 保持窗口大小和qtdesigner中的一致
from PyQt5 import QtCore
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)

yonghu = ['ceshi']
mima = ['ceshi']
gl_name = "admin"
gl_password = "admin"

class loginpage(QWidget, Login):
    def __init__(self):
        super(QWidget, self).__init__()
        self.setupUi(self)

        self.pushButton.clicked.connect(self.ToWelcome)
        self.pushButton_3.clicked.connect(self.tuichu)
        self.pushButton_2.clicked.connect(self.ToRegister)

        # self.lineEdit_3.setEchoMode(QLineEdit.Password) # 设置为密码掩码字符
        # self.lineEdit_2.setEchoMode(QLineEdit.Password)

    def ToWelcome(self):
        yh_name = self.lineEdit.text()
        yh_mima = self.lineEdit_2.text()
        if yh_name != "":
            if yh_mima != "":
                if yh_name in yonghu:
                    if mima[yonghu.index(yh_name)] == yh_mima:
                        QtWidgets.QMessageBox.information(self, "成功", "欢迎用户!")
                        self.w_welcome = welcomepage()
                        self.w_welcome.show()
                        self.close()
                    else:
                        QtWidgets.QMessageBox.critical(self, "失败", "密码错误!")
                else:
                    QtWidgets.QMessageBox.critical(self, "失败", "用户不存在!")
            else:
                QtWidgets.QMessageBox.information(self, "提示", "请输入密码!")
        else:
            QtWidgets.QMessageBox.information(self, "提示", "请输入用户名!")

    def ToRegister(self):
        if self.lineEdit_4.text() != "":
            if self.lineEdit_3.text() != "":
                if self.lineEdit_4.text() == gl_name:
                    if self.lineEdit_3.text() == gl_password:
                        QtWidgets.QMessageBox.information(self, "成功", "欢迎管理员!")
                        self.w_register = registerpage()
                        self.w_register.show()
                        self.close()
                    else:
                        QtWidgets.QMessageBox.critical(self, "失败", "密码错误!")
                else:
                    QtWidgets.QMessageBox.critical(self, "失败", "用户不存在!")
            else:
                QtWidgets.QMessageBox.information(self, "提示", "请输入密码!")
        else:
            QtWidgets.QMessageBox.information(self, "提示", "请输入用户名!")

    def tuichu(self):
        QtWidgets.QMessageBox.information(self, "提示", "感谢使用!")
        self.close()

class welcomepage(QWidget, Welcome):
    def __init__(self):
        super(QWidget, self).__init__()
        self.setupUi(self)

        self.pushButton_2.clicked.connect(self.ToLogin)

    def ToLogin(self):
        QtWidgets.QMessageBox.information(self, "提示", "返回登录!")
        self.w_login = loginpage()
        self.w_login.show()
        self.close()

class registerpage(QWidget, Register):
    def __init__(self):
        super(QWidget, self).__init__()
        self.setupUi(self)

        self.pushButton_2.clicked.connect(self.ToLogin)
        self.pushButton.clicked.connect(self.zhucue)
        self.pushButton_3.clicked.connect(self.xiazai)
        self.pushButton_4.clicked.connect(self.shangchuan_df)
        self.pushButton_5.clicked.connect(self.piliang)

        self.shangchuan_flag = False

    def ToLogin(self):
        welcomepage.ToLogin(self)

    def zhucue(self):
        dai_name = self.lineEdit.text()
        dai_mima = self.lineEdit_2.text()
        if dai_name != "":
            if dai_mima != "":
                if dai_name in yonghu:
                    QtWidgets.QMessageBox.information(self, "提示", "用户已存在,请勿重复注册!")
                else:
                    yonghu.append(dai_name)
                    mima.append(dai_mima)
                    QtWidgets.QMessageBox.information(self, "成功", "注册成功!")
            else:
                QtWidgets.QMessageBox.information(self, "提示", "请输入密码!")
        else:
            QtWidgets.QMessageBox.information(self, "提示", "请输入用户名!")

    def xiazai(self):
        # 设置并下载对应表模板文件
        wb = Workbook()
        ws = wb.active
        ws.column_dimensions['A'].width = 10
        ws.column_dimensions['B'].width = 10
        ws.cell(row=1, column=1, value="用户名")
        ws.cell(row=1, column=2, value="密码")
        wb.save('用户信息模板.xlsx')
        QtWidgets.QMessageBox.information(self, "成功", "用户信息模板下载成功,请查看当前目录!")

    def shangchuan_df(self):
        self.df = shangchuan()
        self.shangchuan_flag = True

    def piliang(self):
        if self.shangchuan_flag == True:
            for col in self.df.columns:
                for row in range(len(self.df)):
                    if col == '用户名':
                        yonghu.append(str(self.df.at[row, col]))
                    if col == '密码':
                        mima.append(str(self.df.at[row, col]))
            QtWidgets.QMessageBox.information(self, '成功', '批量注册成功!')
        else:
            QtWidgets.QMessageBox.critical(self, '提示', '请上传用户信息模板文件!')

def shangchuan():
    filepath, _ = QtWidgets.QFileDialog.getOpenFileName(None, "请选择用户信息模板", "", "XLSX工作表 (*.xlsx)")  # 获取文件路径
    if filepath:
        # 获取原始df
        yuanshi_df = pd.read_excel(filepath)
        if not yuanshi_df.empty:
            QtWidgets.QMessageBox.information(None, "成功", "用户信息模板上传成功!")
            return yuanshi_df
        else:
            QtWidgets.QMessageBox.critical(None, "提示", "请检查操作步骤或模板文件!")
    else:
        QtWidgets.QMessageBox.critical(None, "提示", "请选择XLSX工作表类型!")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w_login = loginpage()
    w_login.show()
    sys.exit(app.exec_())

欢迎留言/私信沟通交流!

相关推荐
技术小甜甜几秒前
[Python] 使用 Tesseract 实现 OCR 文字识别全流程指南
开发语言·python·ocr·实用工具
idkmn_7 分钟前
Daily AI 20251219 (PyTorch基础回顾3)
人工智能·pytorch·python·深度学习·神经网络
Iridescent112114 分钟前
Iridescent:Day28
python
m0_7263658315 分钟前
大力学习台灯T6/T6Pro 救砖实战:macOS/Windows 用 mtkclient 从 Fastboot 无限重启完整恢复(含固件下载地址)
python·github·智能硬件
游戏开发爱好者818 分钟前
苹果 App 上架流程,结合 Xcode、CI 等常见工具
macos·ios·ci/cd·小程序·uni-app·iphone·xcode
free-elcmacom28 分钟前
机器学习高阶教程<7>Transformer原理全景解读:从“序列困境”到“注意力革命”
人工智能·python·机器学习·transformer
RwwH30 分钟前
PyCharm虚拟环境创建
ide·python·pycharm
2501_9151063233 分钟前
用 HBuilder 上架 iOS 应用时如何管理Bundle ID、证书与描述文件
android·ios·小程序·https·uni-app·iphone·webview
码海踏浪36 分钟前
JMeter 时间函数合集
开发语言·python
serve the people37 分钟前
tensorflow 深度解析 Sequential 模型的输入形状指定
人工智能·python·tensorflow