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

最终界面如下:

然后是代码:

import sys
from 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 pyqtSlot
from 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 sys
from PyQt5.QtCore import pyqtSlot
from 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这边借鉴过来的,不一定对,所以欢迎交流讨论。

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

  1. 安全事件日志中的登录事件

    windows日志ID 表 1:安全事件日志中的登录事件 事件 ID 说明 528 用户成功登录计算机. 529 用户使用系统未知的用户名登录,或已知用户使用错误的密码登录. 530 用户帐户在许可的 ...

  2. 如何查看 Windows 服务器中的登录事件

    在 Windows 中,您可以为操作系统检测到的某些事件启用"审核策略".一种这样的审计策略是审计服务器上发生的任何登录/注销事件.这可能是记录哪些帐户正在登录您的服务器.何时以及 ...

  3. 综合设计一个OPPE主页--页面的插件引用(animate.css)--d动画的使用--滚轮或鼠标到该位置时,才有动画的切换---所以我们需要用jquery监听鼠标滚轮的滚动事件

    Animate.css | A cross-browser library of CSS animations. 里面有许多css的效果 首先使用 animate.css文件 link rel=&qu ...

  4. java 监听鼠标点击_java 事件监听 - 鼠标

    java 事件监听 - 鼠标 //事件监听 //鼠标事件监听 //鼠标事件监听有两个实现接口 //1.MouseListener 普通的鼠标操作 //2.MouseMotionListener 鼠标的 ...

  5. js 监听 安卓事件_百行代码实现js事件监听实现跨页面数据传输

    百行代码实现js事件监听实现跨页面数据传输 使用场景 类似消息队列的使用场景,支持同页面和跨页面通信,发送消息和接收消息 技术原理 跨页面通信: 基于事件监听,通过监听 storage事件监听回调机制 ...

  6. 13、Java Swing事件监听:事件处理模型和事件监听器

    事件表示程序和用户之间的交互,例如在文本框中输入,在列表框或组合框中选择,选中复选框和单选框,单击按钮等.事件处理表示程序对事件的响应,对用户的交互或者说对事件的处理是事件处理程序完成的. 当事件发生 ...

  7. cordova监听事件中调用其他方法_Laravel模型事件的实现原理详解

    模型事件在 Laravel 的世界中,你对 Eloquent 大多数操作都会或多或少的触发一些模型事件,下面这篇文章主要给大家介绍了关于Laravel模型事件的实现原理,文中通过示例代码介绍的非常详细 ...

  8. vue监听移动设备的返回事件

    在公共方法文件common.js中实现一个存储当前历史记录的方法 common.js // 存储当前历史记录点,实现控制手机物理返回键的按钮事件 var pushHistory = function ...

  9. java 事件监听应用_Spring Boot应用事件监听示例详解

    前言 本文主要给大家介绍了关于Spring Boot应用事件监听的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 1. Spring Boot特有的应用事件 除了Spring ...

最新文章

  1. SAP AUT10 查看修改记录
  2. Hibernate HQL基础 限定查询条件(这里面有各种条件查询)
  3. python垃圾回收 (GC) 机制
  4. async await实例
  5. display:inline-block的深入理解 转
  6. 图文并茂重新认识下递归
  7. ubuntu16.04+cuda9.0_cudnn7.5+tensorflow-gpu==1.12.0
  8. html页面包含头文件,Web前端技术:HTML部分---Head标签中包含的头文件标签,body标签包含的内部标签...
  9. Per-FedAvg:联邦个性化元学习
  10. “拼木头”算法挑战赛:禁忌搜索算法,用Javascript 跑
  11. java servlet 开发_Java之基于Servlet的Web开发简介
  12. Hibernate POJO在序列化(JSON)时遇到的若干问题
  13. 【C/C++开发】【VS开发】win32位与x64位下各类型长度对比
  14. 提取已有的内核配置文件
  15. Windows开始菜单快捷方式位置(磁贴)
  16. html5空白站位符号,空格代码(隐形空白符号)
  17. 南京邮电大学MOOC高级程序语言设计(C++)第六章编程题答案
  18. 4.8 数值分析: 牛顿迭代法及收敛分析
  19. Android 项目总结(view控件之设置大小和间距)
  20. 山东科技大学计算机学院教师,山东科技大学

热门文章

  1. 【英语学习】【医学】Unit 06 Urine Formation
  2. 【英语学习】【WOTD】mirandize 释义/词源/示例
  3. Intel 64/x86_64/IA-32/x86处理器 - 指令格式(6) - 8086/16位指令位移量字节/立即数字节
  4. Intel 64/x86_64/IA-32/x86处理器 - 通用指令(5) - 控制转移指令
  5. linux多线程加解锁
  6. 混合app用百分比还是rem_[笔记]em, rem最佳实践
  7. QObject::connect: No such signal QGraphicsView::mouseMovePoint(QPoint) in ***
  8. 巴塞尔问题欧拉解法逐步推导与分析
  9. 为虚幻引擎4设置Visual Studio
  10. MongoDB的导入与导出