Python-PyQt5开发学习笔记(四):实战

        我记得我在初识PyQt5时认为,一般都用Qtdesigner辅助UI软件的制作,可学到后面才发现原来真正的大佬写UI真的是用纯代码。我主要的自学资源是B站李宁老师的课,学了大概40来个视频后感觉应该可以先尝试做一个简单的GUI。

        首先构思预期功能:

主要功能:自动读入数据,根据用户选择的算法(供选为:gray-model、kalman、bp-NN)对数据进行拟合。
1.UI运行后有一个登录界面,输入账号和密码,正确进入主界面,错误弹出提示框。
2.主界面左边为功能选择,包括输入数据文件路径、选择方法等,右侧为拟合图形(结果)。

        所涉及到的类如下:

class BPnetwork()    # 神经网络类,完成神经网络拟合
class GM_1_1         # 灰色系统类,完成灰色算法拟合
class KalmanFilter(object)    # kalman类,完成kalman拟合
class mainWindow(QWidget)     # 主界面窗口类
class warningWindow(QDialog)  # 错误提示窗口类
class loginDialog(QDialog)    # 登录界面窗口类
注:class BPnetwork()和class KalmanFilter(object)来源为github

        前三个算法类不是今日重点,今天主要介绍后三个窗口类

        1.登陆窗口

class loginDialog(QDialog):

    def __init__(self):
        super().__init__()
        # 类初始化函数
        self.initUI()

    def initUI(self):
        # 设置窗口名称
        self.setWindowTitle("登录窗口")
        
        # 创建并设置所需要的控件
        namelabel = QLabel()
        passwordlabel = QLabel()
        namelabel.setText("账户:")
        passwordlabel.setText("密码:")
        self.namelineedit = QLineEdit()
        self.passwordlineedit = QLineEdit()
        self.namelineedit.setPlaceholderText("输入账户")
        self.passwordlineedit.setPlaceholderText("输入密码")
        self.passwordlineedit.setEchoMode(QLineEdit.Password)
        buttonOK = QPushButton()
        buttonOK.setText("登录")
        
        # 创建布局
        Layout = QGridLayout()
        Layout.addWidget(namelabel,0,0)
        Layout.addWidget(self.namelineedit,0,1,1,2)
        Layout.addWidget(passwordlabel,1,0)
        Layout.addWidget(self.passwordlineedit,1,1,1,2)
        Layout.addWidget(buttonOK,2,2)
        
        # 设置信号与槽
        buttonOK.clicked.connect(self.transfer)
        
        # 设置布局
        self.setLayout(Layout)

    # 定义槽函数
    def transfer(self):
        name = self.namelineedit.text()
        password = self.passwordlineedit.text()
        name = eval(name)
        password = eval(password)
        # 界面跳转实现
        if name == 4 and password == 123:   # 简单的账户密码设置(此处和设置账户密码规则)
            # 创建主窗口类
            # 注意:不能使用main = mainWindow(),这样类就是一个局部变量,函数运行结束就会被清除,所以得用self.main
            self.main = mainWindow()    
            # 关闭自己(即登录界面)
            self.close()
            # 显示主窗口
            self.main.show()
        else:
            # 创建警告窗口类
            self.warn = warningWindow()
            # 显示警告窗口
            self.warn.show()

其中涉及到的很多控件的API就不一一介绍了,很容易看懂或查到其功能。

         2.警告窗口

class warningWindow(QDialog):

    def __init__(self):
        super().__init__()
        # 类初始函数
        self.initUI()   

    def initUI(self):
        self.setWindowTitle("错误")
        self.resize(300,100)
        label = QLabel()
        label.setText("账号或密码错误!")
        layout = QHBoxLayout()
        layout.addWidget(label)
        self.setLayout(layout)

        3.主界面窗口

class mainWindow(QWidget):

    def __init__(self):
        super().__init__()
        # 初始化类
        self.initUI()

    def initUI(self):
        # 设置窗口名称
        self.setWindowTitle("数据预测系统")

        # 设置窗口大小及位置
        self.setGeometry(300,220,1300,700)

        # 创建所需控件
        self.filepathlabel = QLabel("请输入数据文件完整路径:",self)
        self.filepathlabel.move(50,100)     # 使用绝对布局
        self.filepathLineEdit = QLineEdit(self)
        self.filepathLineEdit.setPlaceholderText("请输入数据文件完整路径")
        self.filepathLineEdit.resize(350,30)
        self.filepathLineEdit.move(50,130)
        self.differlabel = QLabel("数据是否进行差分:",self)
        self.diffoption = QRadioButton(self)
        self.diffoption.setChecked(True)
        self.differlabel.move(50,180)
        self.diffoption.move(210,180)
        self.methodlabel = QLabel("请选择预测方法:",self)
        self.methodlabel.move(50,250)
        self.methodcb = QComboBox(self)
        self.methodcb.addItems(['灰色模型预测','BP神经网络预测','卡尔曼滤波预测'])
        self.methodcb.move(220,248)
        self.BPlabel = QLabel("请输入影响因子数据文件路径: ",self)
        self.BPlabel.move(50,320)
        self.BPdataLineEdit = QLineEdit(self)
        self.BPdataLineEdit.move(50,350)
        self.BPdataLineEdit.resize(350, 30)
        self.BPlabel.setVisible(False)          # 初始化影响因子控件为不可见
        self.BPdataLineEdit.setVisible(False)
        self.predictButton = QPushButton("开始预测",self)
        self.predictButton.move(130,450)

        # 设置信号与槽
        self.predictButton.clicked.connect(self.predict)    # 执行预测
        self.methodcb.currentIndexChanged.connect(self.methodoption)    # 方法切换

        # 设置绘图,此处用了一个教QGroupBox的控件,其控件中可以添加布局
        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure) # 设置画布
        self.fig = QGroupBox(self)
        self.fig.move(500,50)
        self.fig.resize(750,570)
        layout = QVBoxLayout()
        layout.addWidget(self.canvas)   # 将画布加到布局中
        self.fig.setLayout(layout)      # 将布局加到QGroupBox中

    # 槽函数:当方法选中为BP时,将相关控件设置为可见,为其他方法时不可见
    def methodoption(self):
        method = self.sender()
        if method.currentText() == 'BP神经网络预测':
            self.BPlabel.setVisible(True)
            self.BPdataLineEdit.setVisible(True)
        else:
            self.BPlabel.setVisible(False)
            self.BPdataLineEdit.setVisible(False)

    # 槽函数:预测
    def predict(self):
        method = self.methodcb.currentText()
        filepath = self.filepathLineEdit.text()
        df = pd.read_excel(filepath)
        test_data = np.array(df["MD09"], dtype=np.float)
        
        # 差分函数
        def diff(arr):
            res = list()
            res.append(0)
            for i in range(len(arr) - 1):
                res.append(arr[i + 1] - arr[i])
            return res
        
        # 根据控件的选择情况判断是否进行差分
        if self.diffoption.isChecked() == True:
            test_data = diff(test_data)[0:41]
        
        train_data = test_data[0:31]
        # 用if-elif-else控制预测
        if method == "BP神经网络预测":
            plt.cla() # 清空画布 
            # 这是影响因子数据清洗的过程,可跳过
            df2 = pd.read_excel(self.BPdataLineEdit.text())
            data = pd.DataFrame(df2)
            number1 = data['降雨']
            number2 = data['温度']
            ls_data1 = list()
            ls_data2 = list()
            key = True
            count = 1
            while key:
                temp_np1 = np.array(number1)[30 * (count - 1):30 * count]
                temp_np2 = np.array(number2)[30 * (count - 1):30 * count]
                temp_ls1 = list()
                temp_ls2 = list()
                for k in temp_np1:
                    if np.isnan(k):  # 空值判断
                        continue
                    temp_ls1.append(k)
                for j in temp_np2:
                    if np.isnan(j):
                        continue
                    temp_ls2.append(j)
                temp1 = np.array(temp_ls1)
                temp2 = np.array(temp_ls2)
                flag1 = np.sum(temp1) / len(temp1)
                flag2 = np.sum(temp2) / len(temp2)
                ls_data1.append(flag1)
                ls_data2.append(flag2)
                if count * 30 > len(np.array(number1)):
                    break
                count = count + 1
            data1 = np.array(ls_data1, dtype=np.float)
            data2 = np.array(ls_data2, dtype=np.float)
            data = np.vstack((data1[0:31], data2[0:31]))
            data = data.T
            train_data = train_data[0:31]
            count = len(train_data)
            train_data = np.array(train_data)
            label = return_any(train_data.reshape(count,1), 0.1, 1)
            label = label.reshape(len(label), 1)
            bp = BPnetwork([2, 9, 1], 4000)
            bp.train(data, label)
            pred = bp.predict(data)
            
            # 绘图
            plt.plot(label,label="True", marker='x')
            plt.plot(pred,label="BP Prediction",marker="*",c='r')
            plt.legend()
            plt.title("BP Predict")
            plt.grid()
            
            # 将绘制的图在画布上展示
            self.canvas.draw()
        elif method == "灰色模型预测":
            plt.cla()
            GM_model = GM_1_1()
            GM_model.set_model(train_data)
            GM_model.plot()
            self.canvas.draw()
        else:
            plt.cla()
            dt = 1.0 / 60
            F = np.array([[1, dt, 0], [0, 1, dt], [0, 0, 1]])
            H = np.array([1, 0, 0]).reshape(1, 3)
            Q = np.array([[0.05, 0.05, 0.0], [0.05, 0.05, 0.0], [0.0, 0.0, 0.0]])
            R = np.array([0.5]).reshape(1, 1)
            measurements = train_data
            kf = KalmanFilter(F=F, H=H, Q=Q, R=R)
            predictions = []
            for z in measurements:
                predictions.append(np.dot(H, kf.predict())[0])
                kf.update(z)
            test = list()
            for i in range(5):
                test.append(kf.predict()[0])
            plt.plot(range(len(measurements)), measurements, label="Measurements", marker='x',)
            plt.plot(range(len(predictions)), np.array(predictions),
                     c='r', label="Kalman Filter Prediction", marker="*")
            plt.legend()
            plt.title("Kalman Filter Predict")
            plt.grid()
            self.canvas.draw()

     简单介绍一下,目前是拥有一个监测点的15-18年的累计位移监测数据和该地的对应时间序列的降雨和温度数据,位移数据大致的取样间隔为一月,而温度和降雨的取样间隔为一日。在用GM模型和kalman时只需要对位移数据进行差分即可进行建模拟合。而在使用BP建模时需要影响因子一并训练,由于其数据量不统一故需要数据清洗。整体监测数据不便公布,部分原始监测数据如下:

[ 15.  16.  18.  18.  19.  21.  22.  27.  35.  39.  39.  41.  41.  44.  48.  47.  48.  55.  58.  62.  63.  68.  84.  89. 109. 120. 142. 158. 169. 183. 192. 221. 231. 238. 241. 245. 249. 254. 255. 256. 267. 264. 263. 255. 253. 258.]

        最终效果图为(不能放视频就放图片):

Python-PyQt5开发学习笔记(四):实战_第1张图片

Python-PyQt5开发学习笔记(四):实战_第2张图片

 Python-PyQt5开发学习笔记(四):实战_第3张图片

 Python-PyQt5开发学习笔记(四):实战_第4张图片

Python-PyQt5开发学习笔记(四):实战_第5张图片

 Python-PyQt5开发学习笔记(四):实战_第6张图片

 最后附上全部代码请各位读者批评指正!

from PyQt5.QtWidgets import *
import pandas as pd
import numpy as np
import matplotlib
matplotlib.use('Qt5Agg')
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt
import sys

# BP用到模块
def return_any(X, m, n):
    Y = np.zeros_like(X, dtype=np.float64)
    i, j = X.shape
    m = float(m)
    n = float(n)
    X = np.array(X)
    for p in range(j):
        for k in range(i):
            v = (n - m) / (X[:, p].max() - X[:, p].min())
            Y[k, p] = m + v * (X[k, p] - X[:, p].min())
    Y = np.array(Y)
    return Y

class BPnetwork():  # BP预测模型
    def __init__(self, layers_num, epoches):
        assert len(layers_num) == 3, "初始化参数必须为三个"
        self.epoches = epoches
        self.input_size = layers_num[0]
        self.hidden_size = layers_num[1]
        self.output_size = layers_num[2]
        # 初始化权值
        self.X = np.ones([1, self.input_size])
        self.W = np.random.random_sample(size=(self.input_size, self.hidden_size))
        self.V = np.random.random_sample(size=(self.hidden_size, self.output_size))
        self.H = np.ones(self.hidden_size)
        self.Y = np.zeros(self.output_size)
        self.alpha = np.random.random
        self.beta = np.random.random
        self.label = []
        self.error_list = list()
        self.train_end = list()

    def train(self, datas, labels):
        for epoch in range(self.epoches):
            error = 0
            for index in range(datas.shape[0]):
                self.X = np.array(datas[index])
                self.label = np.array(labels[index])
                pred = self.forward()
                if epoch == self.epoches - 1:
                    self.train_end.append(pred[0])
                self.backword()
                for i in range(pred.shape[0]):
                    error += (pred[i] - self.label[i]) * (pred[i] - self.label[i])
            if epoch % 5 == 0:
                self.error_list.append(error)

    def forward(self):
        self.H = np.dot(self.X, self.W)
        self.H = np.array([self.sigmod(i) for i in self.H])
        self.Y = np.dot(self.H, self.V)
        self.Y = np.array([self.sigmod(i) for i in self.Y])
        return self.Y

    def backword(self):
        for j in range(self.V.shape[1]):
            g_j = -(self.label[j] - self.Y[j]) * self.Y[j] * (1 - self.Y[j])
            for i in range(self.V.shape[0]):
                self.V[i][j] = self.V[i][j] - g_j * self.H[i]
        for j in range(self.W.shape[1]):
            delta = 0
            for k in range(self.Y.shape[0]):
                g_k = -(self.label[k] - self.Y[k]) * self.Y[k] * (1 - self.Y[k])
                delta += g_k * self.V[j][k]
            delta = self.H[j] * (1 - self.H[j]) * delta
            for i in range(self.W.shape[0]):
                self.W[i][j] = self.W[i][j] - delta * self.X[i]

    def sigmod(self, x):
        return 1.0 / (1.0 + np.exp(-x))

    def predict(self, data):
        self.X = data
        return self.forward()

# 灰色用到模块
class GM_1_1:

    def __init__(self):
        self.test_data = np.array(())
        self.add_data = np.array(())
        self.argu_a = 0
        self.argu_b = 0
        self.MAT_B = np.array(())
        self.MAT_Y = np.array(())

    def set_model(self,arr):
        self.__acq_data(arr)
        self.__compute()

    def __acq_data(self,arr):
        self.test_data = np.array(arr).flatten()
        add_data = list()
        sum = 0
        for i in range(len(self.test_data)):
            sum = sum + self.test_data[i]
            add_data.append(sum)
        self.add_data = np.array(add_data)
        ser = list()
        for i in range(len(self.add_data)-1):
            temp = (-1) * ((1/6)*self.add_data[i] + (5/6)*self.add_data[i+1])
            ser.append(temp)
        B = np.vstack((np.array(ser).flatten(),np.ones(len(ser),).flatten()))
        self.MAT_B = np.array(B).T
        Y = np.array(self.test_data[1:])
        self.MAT_Y = np.reshape(Y,(len(Y),1))

    def __compute(self):
        temp_1 = np.dot(self.MAT_B.T,self.MAT_B)
        temp_2 = np.matrix(temp_1).I
        temp_3 = np.dot(np.array(temp_2),self.MAT_B.T)
        vec = np.dot(temp_3,self.MAT_Y)
        self.argu_a = vec.flatten()[0]
        self.argu_b = vec.flatten()[1]

    def predict(self,k):
        part_1 = 1-pow(np.e,self.argu_a)
        part_2 = self.test_data[0] - self.argu_b/self.argu_a
        part_3 = pow(np.e,(-1)*self.argu_a*k)
        return part_1*part_2*part_3

    def plot(self):
        pre = list()
        pre.append(self.test_data[0])
        for i in range(len(self.test_data) - 1):
            pre.append(self.predict(i + 2))
        plt.plot([i for i in range(1, len(self.test_data) + 1)], self.test_data, marker='x', label='True')
        plt.plot([i for i in range(1, len(self.test_data) + 1)], pre, c='r', marker='*', label='Predicton')
        plt.title("Gray Model Prediction")
        plt.grid()
        plt.legend()

# 卡尔曼滤波用到模块
class KalmanFilter(object):
    def __init__(self, F=None, B=None, H=None, Q=None, R=None, P=None, x0=None):
        if F is None or H is None:
            raise ValueError("Set proper system dynamics.")

        self.n = F.shape[1]
        self.m = H.shape[1]
        self.F = F
        self.H = H
        self.B = 0 if B is None else B
        self.Q = np.eye(self.n) if Q is None else Q
        self.R = np.eye(self.n) if R is None else R
        self.P = np.eye(self.n) if P is None else P
        self.x = np.zeros((self.n, 1)) if x0 is None else x0

    def predict(self, u=0):
        # print(self.x)
        self.x = np.dot(self.F, self.x) + np.dot(self.B, u)
        self.P = np.dot(np.dot(self.F, self.P), self.F.T) + self.Q
        return self.x

    def update(self, z):
        # print(self.x)
        y = z - np.dot(self.H, self.x)
        S = self.R + np.dot(self.H, np.dot(self.P, self.H.T))
        K = np.dot(np.dot(self.P, self.H.T), np.linalg.inv(S))
        self.x = self.x + np.dot(K, y)
        I = np.eye(self.n)
        self.P = np.dot(
            np.dot(I - np.dot(K, self.H), self.P), (I - np.dot(K, self.H)).T
        ) + np.dot(np.dot(K, self.R), K.T)

class mainWindow(QWidget):

    def __init__(self):
        super().__init__()
        # 初始化类
        self.initUI()

    def initUI(self):
        # 设置窗口名称
        self.setWindowTitle("数据预测系统")

        # 设置窗口大小及位置
        self.setGeometry(300,220,1300,700)

        # 创建所需控件
        self.filepathlabel = QLabel("请输入数据文件完整路径:",self)
        self.filepathlabel.move(50,100)     # 使用绝对布局
        self.filepathLineEdit = QLineEdit(self)
        self.filepathLineEdit.setPlaceholderText("请输入数据文件完整路径")
        self.filepathLineEdit.resize(350,30)
        self.filepathLineEdit.move(50,130)
        self.differlabel = QLabel("数据是否进行差分:",self)
        self.diffoption = QRadioButton(self)
        self.diffoption.setChecked(True)
        self.differlabel.move(50,180)
        self.diffoption.move(210,180)
        self.methodlabel = QLabel("请选择预测方法:",self)
        self.methodlabel.move(50,250)
        self.methodcb = QComboBox(self)
        self.methodcb.addItems(['灰色模型预测','BP神经网络预测','卡尔曼滤波预测'])
        self.methodcb.move(220,248)
        self.BPlabel = QLabel("请输入影响因子数据文件路径: ",self)
        self.BPlabel.move(50,320)
        self.BPdataLineEdit = QLineEdit(self)
        self.BPdataLineEdit.move(50,350)
        self.BPdataLineEdit.resize(350, 30)
        self.BPlabel.setVisible(False)          # 初始化影响因子控件为不可见
        self.BPdataLineEdit.setVisible(False)
        self.predictButton = QPushButton("开始预测",self)
        self.predictButton.move(130,450)

        # 设置信号与槽
        self.predictButton.clicked.connect(self.predict)    # 执行预测
        self.methodcb.currentIndexChanged.connect(self.methodoption)    # 方法切换

        # 设置绘图,此处用了一个教QGroupBox的控件,其控件中可以添加布局
        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure) # 设置画布
        self.fig = QGroupBox(self)
        self.fig.move(500,50)
        self.fig.resize(750,570)
        layout = QVBoxLayout()
        layout.addWidget(self.canvas)   # 将画布加到布局中
        self.fig.setLayout(layout)      # 将布局加到QGroupBox中

    # 槽函数:当方法选中为BP时,将相关控件设置为可见,为其他方法时不可见
    def methodoption(self):
        method = self.sender()
        if method.currentText() == 'BP神经网络预测':
            self.BPlabel.setVisible(True)
            self.BPdataLineEdit.setVisible(True)
        else:
            self.BPlabel.setVisible(False)
            self.BPdataLineEdit.setVisible(False)

    # 槽函数:预测
    def predict(self):
        method = self.methodcb.currentText()
        filepath = self.filepathLineEdit.text()
        df = pd.read_excel(filepath)
        test_data = np.array(df["MD09"], dtype=np.float)

        # 差分函数
        def diff(arr):
            res = list()
            res.append(0)
            for i in range(len(arr) - 1):
                res.append(arr[i + 1] - arr[i])
            return res

        # 根据控件的选择情况判断是否进行差分
        if self.diffoption.isChecked() == True:
            test_data = diff(test_data)[0:41]

        train_data = test_data[0:31]
        # 用if-elif-else控制预测
        if method == "BP神经网络预测":
            plt.cla() # 清空画布
            # 这是影响因子数据清洗的过程,可跳过
            df2 = pd.read_excel(self.BPdataLineEdit.text())
            data = pd.DataFrame(df2)
            number1 = data['降雨']
            number2 = data['温度']
            ls_data1 = list()
            ls_data2 = list()
            key = True
            count = 1
            while key:
                temp_np1 = np.array(number1)[30 * (count - 1):30 * count]
                temp_np2 = np.array(number2)[30 * (count - 1):30 * count]
                temp_ls1 = list()
                temp_ls2 = list()
                for k in temp_np1:
                    if np.isnan(k):  # 空值判断
                        continue
                    temp_ls1.append(k)
                for j in temp_np2:
                    if np.isnan(j):
                        continue
                    temp_ls2.append(j)
                temp1 = np.array(temp_ls1)
                temp2 = np.array(temp_ls2)
                flag1 = np.sum(temp1) / len(temp1)
                flag2 = np.sum(temp2) / len(temp2)
                ls_data1.append(flag1)
                ls_data2.append(flag2)
                if count * 30 > len(np.array(number1)):
                    break
                count = count + 1
            data1 = np.array(ls_data1, dtype=np.float)
            data2 = np.array(ls_data2, dtype=np.float)
            data = np.vstack((data1[0:31], data2[0:31]))
            data = data.T
            train_data = train_data[0:31]
            count = len(train_data)
            train_data = np.array(train_data)
            label = return_any(train_data.reshape(count,1), 0.1, 1)
            label = label.reshape(len(label), 1)
            bp = BPnetwork([2, 9, 1], 4000)
            bp.train(data, label)
            pred = bp.predict(data)

            # 绘图
            plt.plot(label,label="True", marker='x')
            plt.plot(pred,label="BP Prediction",marker="*",c='r')
            plt.legend()
            plt.title("BP Predict")
            plt.grid()

            # 将绘制的图在画布上展示
            self.canvas.draw()
        elif method == "灰色模型预测":
            plt.cla()
            GM_model = GM_1_1()
            GM_model.set_model(train_data)
            GM_model.plot()
            self.canvas.draw()
        else:
            plt.cla()
            dt = 1.0 / 60
            F = np.array([[1, dt, 0], [0, 1, dt], [0, 0, 1]])
            H = np.array([1, 0, 0]).reshape(1, 3)
            Q = np.array([[0.05, 0.05, 0.0], [0.05, 0.05, 0.0], [0.0, 0.0, 0.0]])
            R = np.array([0.5]).reshape(1, 1)
            measurements = train_data
            kf = KalmanFilter(F=F, H=H, Q=Q, R=R)
            predictions = []
            for z in measurements:
                predictions.append(np.dot(H, kf.predict())[0])
                kf.update(z)
            test = list()
            for i in range(5):
                test.append(kf.predict()[0])
            plt.plot(range(len(measurements)), measurements, label="Measurements", marker='x',)
            plt.plot(range(len(predictions)), np.array(predictions),
                     c='r', label="Kalman Filter Prediction", marker="*")
            plt.legend()
            plt.title("Kalman Filter Predict")
            plt.grid()
            self.canvas.draw()

class warningWindow(QDialog):

    def __init__(self):
        super().__init__()
        # 类初始函数
        self.initUI()

    def initUI(self):
        self.setWindowTitle("错误")
        self.resize(300,100)
        label = QLabel()
        label.setText("账号或密码错误!")
        layout = QHBoxLayout()
        layout.addWidget(label)
        self.setLayout(layout)

class loginDialog(QDialog):

    def __init__(self):
        super().__init__()
        # 类初始化函数
        self.initUI()

    def initUI(self):
        # 设置窗口名称
        self.setWindowTitle("登录窗口")

        # 创建并设置所需要的控件
        namelabel = QLabel()
        passwordlabel = QLabel()
        namelabel.setText("账户:")
        passwordlabel.setText("密码:")
        self.namelineedit = QLineEdit()
        self.passwordlineedit = QLineEdit()
        self.namelineedit.setPlaceholderText("输入账户")
        self.passwordlineedit.setPlaceholderText("输入密码")
        self.passwordlineedit.setEchoMode(QLineEdit.Password)
        buttonOK = QPushButton()
        buttonOK.setText("登录")

        # 创建布局
        Layout = QGridLayout()
        Layout.addWidget(namelabel,0,0)
        Layout.addWidget(self.namelineedit,0,1,1,2)
        Layout.addWidget(passwordlabel,1,0)
        Layout.addWidget(self.passwordlineedit,1,1,1,2)
        Layout.addWidget(buttonOK,2,2)

        # 设置信号与槽
        buttonOK.clicked.connect(self.transfer)

        # 设置布局
        self.setLayout(Layout)

    # 定义槽函数
    def transfer(self):
        name = self.namelineedit.text()
        password = self.passwordlineedit.text()
        name = eval(name)
        password = eval(password)
        # 界面跳转实现
        if name == 4 and password == 123:   # 简单的账户密码设置(此处和设置账户密码规则)
            # 创建主窗口类
            # 注意:不能使用main = mainWindow(),这样类就是一个局部变量,函数运行结束就会被清除,所以得用self.main
            self.main = mainWindow()
            # 关闭自己(即登录界面)
            self.close()
            # 显示主窗口
            self.main.show()
        else:
            # 创建警告窗口类
            self.warn = warningWindow()
            # 显示警告窗口
            self.warn.show()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = loginDialog()
    window.show()
    sys.exit(app.exec_())



你可能感兴趣的:(Python-PyQt5开发,python,pyqt5)