900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 宽度发生变化事件监听_PyQt5(3) :实现登录 事件监听处理 程序逻辑功能和界面分离...

宽度发生变化事件监听_PyQt5(3) :实现登录 事件监听处理 程序逻辑功能和界面分离...

时间:2023-09-27 14:45:32

相关推荐

宽度发生变化事件监听_PyQt5(3) :实现登录 事件监听处理 程序逻辑功能和界面分离...

学习于: 学点编程吧:PyQt5图形界面编程(目录)

最终界面如下:

然后是代码:

import sysfrom PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox, QLineEdit, QLabelclass Example(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setGeometry(300, 300, 400, 300)self.bt1 = QPushButton('登录', self)self.bt1.setGeometry(115, 150, 70 ,30)self.bt1.clicked.connect(self.showMessage) # 相当于就是建立了一个click的处理事件self.usr = QLabel("用户:", self) # 这里的好像都需要把self作为第二个参数传进去才能显示出来self.usr.setGeometry(50, 50, 30, 30)self.pwd = QLabel("密码:", self)self.pwd.setGeometry(50, 80, 30, 30)self.text1 = QLineEdit(self)#没有self的话连框都出不来self.text1.selectAll()self.text1.setFocus()self.text1.setGeometry(80, 50, 150 ,30)self.text2 = QLineEdit( self)self.text2.selectAll()self.text2.setFocus()self.text2.setGeometry(80, 80, 150 ,30)self.text2.setEchoMode(QLineEdit.Password)self.show() def showMessage(self):acount = self.text1.text() #这里text应该不需要转为字符串吧,返回的应该就是一个字符串。password= self.text2.text()print(acount)print(password)if len(password) == 0:QMessageBox.warning(self, "警告", "密码为空")else:QMessageBox.warning(self, "警告", "密码长度低于6位")if acount == "jackhe" and password == "123456" :QMessageBox.about(self, '','登录成功')else:QMessageBox.about(self, '','登录失败!') def closeEvent(self, event):reply = QMessageBox.question(self, '确认', '确认退出吗', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)if reply == QMessageBox.Yes:event.accept() else:event.ignore()if __name__ == '__main__':app = QApplication(sys.argv)ex = Example()sys.exit(app.exec_())

先讲我写完之后的第一感受吧:

感觉这个很捞,因为我发现从知乎上复制下来的不知道为啥会有缩进错误,然后干脆自己重写了一遍,或者是回退到上一行,有分号的enter一下就好。对我这个python小白来说,python的缩进真的恶心,压根看不出来哪里缩进不对,各种报indent。。Java的括号多舒服啊! 然后是忽然记起来python的变量不需要声明,直接使用就行,我第一反应就是去找哪里声明的,,尴尬。还有就是它不会自己自动导包,你需要啥包得自己去import,尴尬。还有就是里面的self的使用泛滥得不是你所能想象,调用方法必须来一个self,使用变量可以来个self。

然后回到我们得代码中来,看看怎么写这个登录界面吧。

(下面的构造函数是我从Java里引入的概念,感觉也是这个概念,大家自行理解)

先看第一步:

if __name__ == '__main__':app = QApplication(sys.argv)ex = Example()sys.exit(app.exec_())

这个就不多解释了,前面文章中已经讲过了,中间是创建对象,创建对象就默认调用构造函数,构造函数中就创建UI。然后就进行应用程序的主循环。

然后看主要代码:

def __init__(self):super().__init__()self.initUI()

构造函数调用创建UI的方法。

self.setGeometry(300, 300, 400, 300)self.bt1 = QPushButton('登录', self)self.bt1.setGeometry(115, 150, 70 ,30)self.bt1.clicked.connect(self.showMessage) # 相当于就是建立了一个click的处理事件self.usr = QLabel("用户:", self) # 这里的好像都需要把self作为第二个参数传进去才能显示出来self.usr.setGeometry(50, 50, 30, 30)self.pwd = QLabel("密码:", self)self.pwd.setGeometry(50, 80, 30, 30)self.text1 = QLineEdit(self)#没有self的话连框都出不来self.text1.selectAll()self.text1.setFocus()self.text1.setGeometry(80, 50, 150 ,30)self.text2 = QLineEdit( self)self.text2.selectAll()self.text2.setFocus()self.text2.setGeometry(80, 80, 150 ,30)self.text2.setEchoMode(QLineEdit.Password)

setGeometry(x,y,width,height) 前两个参数是窗口的x和y位置;第三个是宽度;第四个是窗口的高度。也就是它在一个方法中组合了resize()和move()方法。 这里注意啊!往右是x,往下是y。别搞错了。

self.setGeometry设置的是整个窗体相对显示器的位置。后面的self.usr,pwd ,text1之类的都是相对于窗体的左上角的位置。这个就是确定相对位置的方法,感觉很麻烦。 pyqt5还有另外一种布局方式,可以参考 :学点编程吧:PyQt5系列教程(6):布局 ,和Java的布局差不多吧。

然后这里也是使用了几个组件,感觉很简单,就不讲了,我都是 学点编程吧:PyQt5图形界面编程(目录) 这里一搜,然后一看就用就完事了。

这里注意: 密码框是要在输入的时候不显示出输入的字符, 它本质还是QLineEdit,只是设置了 self.text2.setEchoMode(QLineEdit.Password) 这个属性而已。

然后其它的就没什么了,来到最关键的事件监听和处理上来,也就是:

self.bt1.clicked.connect(self.showMessage)

这段代码,bt1是一个button对象,clickd是这个button对象拥有的一个事件,也就是按一下会产生的影响,connect就是把这个影响传递到showMessage这个方法中。 这个是我最简单的理解方式了,我写过Java界面,安卓界面,前端,所以理解这个比较快。 学点编程吧:PyQt5系列教程(5):事件与信号处理 这里写得就非常系统具体,大家可以学习一波。 我想着值得注意的是 :

keyPressEvent(self, e) 按键时的监听,也就是监听你按下键盘的什么键。mouseMoveEvent(self, event) 移动鼠标时的监听,比如获取鼠标当前所在所在位置信息paintEvent(self, event) 重绘方法,这个我暂时理解位Java的重绘,也就是比如窗体的刷新,放大缩小等改变所导致的界面重绘(具体的话后面使用到再细说)sender()获取事件发送者的信息,从而根据源来判断反应。s = Signal()s.showmouse.connect(某个方法) :鼠标点击后运行的方法

感觉还是挺简单的,封装得比Java还好。调用起来贼方便。

然后最后看我们得事件处理方法:

def showMessage(self):acount = self.text1.text() #这里text应该不需要转为字符串吧,返回的应该就是一个字符串。password= self.text2.text()print(acount)print(password)if len(password) == 0:QMessageBox.warning(self, "警告", "密码为空")else:QMessageBox.warning(self, "警告", "密码长度低于6位")if acount == "jackhe" and password == "123456" :QMessageBox.about(self, '','登录成功')else:QMessageBox.about(self, '','登录失败!') def closeEvent(self, event):reply = QMessageBox.question(self, '确认', '确认退出吗', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)if reply == QMessageBox.Yes:event.accept() else:event.ignore()

showMessage是点击按钮后的反应:获取输入文本,进行相应的逻辑处理。

closeEvent是重写了方法,代表的是点击最右上角的 x 后的事件,也就是关闭窗口的事件。

不由得感叹这个有点PyQt5有点牛逼啊!

然后接下来,我们QT designer结合eric6再来重做一遍这个功能。

先是新建一个project,然后在选择存储路径的时候,每个项目都单独分出一个文件夹。

ok后进入forms界面:

然后右键空白处,选择new form.

然后选择个基本类型为main windows. 后ok。运行QT designer如下

注意红色标记部分。

然后开始创建我们的登录界面。然后就是把左边的小部件拖拽过来就ok(左键按住拖拽)。如下图,找不到的部件可以直接在左上角的搜索框进行搜索。

然后注意啦,此时我们输入密码是不会隐藏字符的,所以需要把这个edit line的属性echo mode设置为password,如下图(因此后面有类似的都可以用这样的方法进行修改。),此后再输入字符即会变成隐藏字符。

怎么样,是不是感觉这个搞界面简单多了,而且好看多了。关键是不用自己去尝试慢慢修改每个组件的大小和位置了。这个就很舒服。注意,此时在QTdesigner这里一定要点击保存!ctrl+S,以后每次修改界面都要进行保存,然后重新进行后面的编译!

然后这个时候我们回到 eric6 ,点击form界面

然后右键编译 compile all forms

然后进入左边的sources界面:可以发现多了一份py代码,可以进入代码按住F2运行,然后直接点击ok即可

运行效果如下:

也就是说,到这里为止,我们已经把界面做完了,但是里面的逻辑功能啥的都没有。所以,接下来我们要编写逻辑部分代码。

此时我们回到eric6中,进入form界面,右键ui文件,选择 generate dialog code, 然后new,选择类名和文件名。

OK之后,然后把下面的click加上。

然后ok。然后进入source界面:你会发现你多了一个action.py文件,如下图:

这个文件是导入了你刚才的界面模块,然后我们在这里写我们的逻辑代码。刚生成的逻辑代码如下:

from PyQt5.QtCore import pyqtSlotfrom PyQt5.QtWidgets import QMainWindowfrom .Ui_login import Ui_MainWindowclass Action(QMainWindow, Ui_MainWindow):"""Class documentation goes here."""def __init__(self, parent=None):"""Constructor@param parent reference to the parent widget@type QWidget"""super(Action, self).__init__(parent)self.setupUi(self)@pyqtSlot()def on_pushButton_clicked(self):"""Slot documentation goes here."""# TODO: not implemented yetraise NotImplementedError

我们现在要修改这个代码变成我们想要的逻辑功能,我们在这个文件里导入了前面的main windows,所以我们是要在这个文件里运行,所以我们先加上

if __name__ == "__main__":

然后从这里开始。如下图:警告的意思就是我们没导入相应的包。import进来即可。

然后到主逻辑:其实就是把我们之前写的showMessage的东西迁移过来。不过此时要注意名字的改变。

报错1:

原因:导入包不成功 解决方案:删除from后的那一点

报错2:

原因:没有导入sys包 解决方案:import sys

最后在action.py中 F2后如下:

完整代码如下: 先是UI_login.py

# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'D:UsersDELLeric6workdirectoryqt3loginlogin.ui'## Created by: PyQt5 UI code generator 5.6## WARNING! All changes made in this file will be lost!from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(800, 600)self.centralWidget = QtWidgets.QWidget(MainWindow)self.centralWidget.setObjectName("centralWidget")self.lineEdit = QtWidgets.QLineEdit(self.centralWidget)self.lineEdit.setGeometry(QtCore.QRect(260, 160, 113, 20))self.lineEdit.setObjectName("lineEdit")self.lineEdit_2 = QtWidgets.QLineEdit(self.centralWidget)self.lineEdit_2.setGeometry(QtCore.QRect(260, 190, 113, 20))self.lineEdit_2.setEchoMode(QtWidgets.QLineEdit.Password)self.lineEdit_2.setObjectName("lineEdit_2")self.label = QtWidgets.QLabel(self.centralWidget)self.label.setGeometry(QtCore.QRect(230, 160, 31, 21))self.label.setObjectName("label")self.label_2 = QtWidgets.QLabel(self.centralWidget)self.label_2.setGeometry(QtCore.QRect(230, 190, 54, 21))self.label_2.setObjectName("label_2")self.pushButton = QtWidgets.QPushButton(self.centralWidget)self.pushButton.setGeometry(QtCore.QRect(260, 230, 75, 23))self.pushButton.setObjectName("pushButton")MainWindow.setCentralWidget(self.centralWidget)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))self.label.setText(_translate("MainWindow", "账号"))self.label_2.setText(_translate("MainWindow", "密码"))self.pushButton.setText(_translate("MainWindow", "登录"))if __name__ == "__main__":import sysapp = QtWidgets.QApplication(sys.argv)MainWindow = QtWidgets.QMainWindow()ui = Ui_MainWindow()ui.setupUi(MainWindow)MainWindow.show()sys.exit(app.exec_())

然后是action.py:

# -*- coding: utf-8 -*-"""Module implementing Action."""import sysfrom PyQt5.QtCore import pyqtSlotfrom PyQt5.QtWidgets import *from Ui_login import Ui_MainWindowclass Action(QMainWindow, Ui_MainWindow):def __init__(self, parent=None):super(Action, self).__init__(parent)self.setupUi(self)self.show()@pyqtSlot()def on_pushButton_clicked(self):acount = self.lineEdit.text() #这里text应该不需要转为字符串吧,返回的应该就是一个字符串。password= self.lineEdit_2.text()print(acount)print(password)if len(password) == 0:QMessageBox.warning(self, "警告", "密码为空")else:QMessageBox.warning(self, "警告", "密码长度低于6位")if acount == "jackhe" and password == "123456" :QMessageBox.about(self, '','登录成功')else:QMessageBox.about(self, '','登录失败!') def closeEvent(self, event):reply = QMessageBox.question(self, '确认', '确认退出吗', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)if reply == QMessageBox.Yes:event.accept() else:event.ignore()if __name__ == "__main__":app = QApplication(sys.argv)action = Action()sys.exit(app.exec_())

这里的closeEven是我另外加的,按理说应该可以在创建action.py哪里进行选择的。这里忘记了。所以直接自己重写了一个。

这样,我们就实现了界面和逻辑处理的分离。 虽然看起来代码挺多的,但是我们实际写的代码只是逻辑处理部分。

然后我们来分析一下这个自动生成的代码:

首先是UI_login.py:

因为我们运行的是action.py,所以这里的main部分就不用看了。

首先是setupUI,这里就是把整个界面搭建起来,retranslateUi就是把lable和button的文字输入进去。这里是一个界面和文字的分离。

然后看我们重点的action.py。

class Action(QMainWindow, Ui_MainWindow): 这里也就是说它继承了前面的UI_mainwindow这个类,所以这里也就是说这个action类拥有了父类的界面,然后self.show就直接显示出来了。 也就是说,这个实际上是把界面设计放在父类当中,然后把逻辑处理放在子类当中。 然后子类拥有父类的各种属性,比如edit line,label之类的,可以自由操作这些东西。然后运行起来就ok了。

嗯,感觉差不多就是这样了。不得不说这个设计得还是很精妙的。

没错,今天就先到这里了。

这里有很多思想都是我从Java这边借鉴过来的,不一定对,所以欢迎交流讨论。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。