目录
1. 前言
2. 环境配置
3. 主页面
3.1. 创建一个页面
3.2. 添加相关控件
3.2.1. 添加标签
3.2.2. 添加输入框
3.2.3. 添加按钮
3.2.4. 设置背景
4. 注册页面
5. 逻辑关系
前言
上一次利用tkinter
设计了一个登陆注册界面受到了很多小伙伴的关注(传送门),于是想着利用PyQt
来实现,当然是因为 ,并且这一次我们使用PyQt
长的好看呀数据库
来存储用户信息,是不是一下子比上一次逼格了不少,先看看效果吧
![演示](img-blog.csdnimg.cn/20191127125… =600x)
下面马上开始吧
环境配置
- 下载安装 python
- 安装配置编辑器
- 下载所需库
前面的两个内容在之前的教程中已经解决了,接下来我们来下载安装所要使用的库, 只需要运行以下的命令便可以安装 PyQt5
了,不过时间可能稍微长一点,耐心等待~~
pip install PyQt5
主页面
1. 创建一个页面
对于新手来说最简单粗暴的方法为,在这里我们使用此种方式[1]
from PyQt5.Qt import *
除此之外我们还需要导入sys
模块
import sys
然后利用下面代码创建一个主页面
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
self.set_ui()
def set_ui(self):
self.resize(1000, 800)
self.setWindowTitle(' Login in')
app = QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
在上面的代码中我们首先导入了所需要的模块
QApplication
-> 应用程序,一个程序只能有一个应用程序接口QMainWindow
-> 主窗口,一个程序也只能有一个主窗口sys
-> 获取系统的信息,比如命令行的,并且承担关闭窗口后完全退出的责任
然后我们使用
resize
-> 设置窗口的大小setWindowTitle
-> 设置窗口的标题
接着使用
app = QApplication(sys.argv)
创建一个应用- 创建一个窗口
window
并且调用show
方法来显示窗口[2] app.exec_()
可以让窗口一直运行知道被关闭,类似于tkinter
中的mainloop
方法sys.exit(app.exec_())
可以用来判断程序是否正常退出
运行之后,我们可以看到以下界面,和平常所见的是不是一模一样!
我们还可以使用下面的代码为我们的图像添加一个图标
def change_icon(self):
"""用来修改图像的图标"""
self.icon = QIcon("python-logo.png")
self.setWindowIcon(self.icon)
添加图标之后,界面得到进一步的美化,接下来我们将对我们的界面添加一些控件与用户进行交互
2. 添加相关控件
2.1 添加标签
类似tkinter中的Label
, QLabel
为PyQt中提供的标签对象,我们可以使用下面的代码实现标签的添加
def add_label(self):
self.label = QLabel(self)
self.label.setText('username')
self.label.setFixedSize(240, 40)
self.label.move(120, 530)
在上述代码中,我们首先定义了一个QLabel
对象,然后使用其中的方法[3]
setText
-> 设置文本内容
setFixedSize
-> 设置不可修改的窗口大小
然后我们来设置以下字体,利用 QFont
对象来创建一个字体对象,然后使用QLabel
对象的setFont
方法进行设置
# 设置字体
label_font = QFont()
label_font.setFamily('Consolas')
label_font.setPixelSize(35)
self.label.setFont(label_font)
QFont
中的方法[3:1]:
setFamily
-> 设置字体
setPixelSize
-> 设置字体大小
运行之后我们可以得到之下的效果
然后同样的添加 password
等文字标签,全部代码如下:
def add_label(self):
"""添加相应的标签"""
# 设置字体
label_font = QFont()
label_font.setFamily('Consolas')
label_font.setPixelSize(35)
# 创建文本标签
self.username_label = QLabel(self)
self.password_label = QLabel(self)
self.cyberits_label = QLabel(self)
# 设置标签中的文本
self.username_label.setText("username")
self.password_label.setText("password")
self.cyberits_label.setText("Cyberist--a python learner")
# 设置标签的大小
self.cyberits_label.setFixedSize(600, 40)
self.username_label.setFixedSize(240, 40)
self.password_label.setFixedSize(240, 40)
# 设置标签的位置
self.username_label.move(120, 530)
self.password_label.move(120, 600)
self.cyberits_label.move(280, 700)
self.username_label.setFont(label_font)
self.password_label.setFont(label_font)
label_font.setPixelSize(30)
self.cyberits_label.setFont(label_font)
在创建控件的参数中加入另外一个控件(此处为
self
)可以将创建的参数视为子控件,没有外围的放大关闭等按钮,否则显示的时候需要调用本身的show
方法
2.2 添加输入框
在PyQt5
中提供了QLineEdit
可以实现获取用户的输入,使用下面的方法便可以实现对输入框的添加
def add_line_edit(self):
"""添加输入框"""
line_edit_font = QFont()
line_edit_font.setFamily('Consolas')
line_edit_font.setPixelSize(30)
# 创建
self.username_edit = QLineEdit(self)
self.password_edit = QLineEdit(self)
# 设置密码格式
self.password_edit.setEchoMode(QLineEdit.Password)
# 设置字体
self.username_edit.setFont(line_edit_font)
self.password_edit.setFont(line_edit_font)
# 设置占位符
self.username_edit.setPlaceholderText("username")
self.password_edit.setPlaceholderText("password")
# 设置大小
self.username_edit.setFixedSize(350, 40)
self.password_edit.setFixedSize(350, 40)
# 设置位置
self.username_edit.move(320, 530)
self.password_edit.move(320, 600)
在上述代码中
QLineEdit
-> 定义一个输入框对象
setEchoMode(QLineEdit.Password)
-> 设置输入的时候显示的为我们平常所见的小圆点,无法看到其中的文本内容
setText
-> 对其中的文本进行设置
setPlaceholderText
-> 设置其中的占位符,相当于提示信息
setFixedSize
-> 设置固定的大小
move
-> 定位
于是,我们便可以获得下面的效果
2.3 添加按钮
QPushButton
可以帮我们实现按钮的功能,其使用方法和之前的标签,输入框的使用是类似的,在这里不再赘述,直接上代码:
def add_button(self):
"""添加按钮"""
button_font = QFont()
button_font.setFamily('Consolas')
button_font.setPixelSize(30)
# 创建按钮对象
self.login_button = QPushButton("Login", self)
self.sign_button = QPushButton(self)
# 修改大小且不可变
self.login_button.setFixedSize(160, 50)
self.sign_button.setFixedSize(160, 50)
# 设置字体
self.login_button.setFont(button_font)
self.sign_button.setFont(button_font)
# 设置位置
self.login_button.move(750, 530)
self.sign_button.move(750, 600)
# 设置文本提示内容
self.login_button.setText("Login in")
self.sign_button.setText("Sign up")
# 实现功能,按钮点击之后执行的动作
self.login_button.clicked.connect(self.login)
self.sign_button.clicked.connect(self.sign_up_window)
上面值得注意的是使用了信号和槽
,当按钮被用户clicked
的时候便会执行参数中的动作,在这里分别为登录和注册功能,此外还有许多的信号,在之后的专栏中会提到,届时谢谢关注
2.4 设置背景
设置背景的时候,我们可以使用QFrame
对象,并在其上设置一下背景图片,如果直接设置的话,可能不太好操作和理解,但是注意,在绘制中,首先绘制的会在窗口的后端,后绘制的会在前端,所以要先创建背景,然后在设置之前的效果,否则可能出现意想不到的效果[4],实现代码如下:
def set_background_image(self):
"""添加背景图片"""
self.frame = QFrame(self)
self.frame.resize(1000, 520)
self.frame.move(40, 150)
self.frame.setStyleSheet(
'background-image: url("./python.png"); background-repeat: no-repeat; text-align:center;')
首先创建一个QFrame
对象,然后控制其大小和位置,最后使用setStyleSheet
对其进行设置,其参数可以是类似css
样式的字符串,或者说是qss
[5]
到这里,我们对主页面的外观设置已经完成了,样式如图(个人觉得比tkinter好看多了):
注册页面
界面设计
注册页面和主页面比较相似,先看看实现之后的样式吧: 具体的代码如下,这里不再赘述,和登录的主页面实现是完全类似的
class SignWindow(QWidget):
def __init__(self):
super(SignWindow, self).__init__()
self.setWindowTitle("Sign up") # 设置标题
self.resize(1000, 800) # 设置窗口的大小
self.set_ui() # 调用其他的设计方法
def set_ui(self): # 集合所有的设计
self.add_line_edit()
self.add_button()
self.add_label()
def add_label(self):
"""添加相应的标签"""
# 设置文本的字体
label_font = QFont()
label_font.setFamily('Consolas')
label_font.setPixelSize(35)
# 创建三个对应的标签,父窗口为 self
self.username_label = QLabel(self)
self.password_label = QLabel(self)
self.cyberits_label = QLabel(self)
self.confirm_label = QLabel(self)
# 相应的标签设置文本
self.username_label.setText("username")
self.password_label.setText("password")
self.confirm_label.setText("confirmed")
self.cyberits_label.setText("Cyberist--a python learner")
# 控制label的大小 fixedSize表示之后无法修改
self.cyberits_label.setFixedSize(600, 40)
self.username_label.setFixedSize(240, 40)
self.password_label.setFixedSize(240, 40)
self.confirm_label.setFixedSize(240, 40)
# 设置对应的位置,注意move不是移动多少,而是直接移动到
self.username_label.move(120, 530)
self.password_label.move(120, 600)
self.cyberits_label.move(280, 730)
self.confirm_label.move(120, 670)
# 设置字体
self.username_label.setFont(label_font)
self.password_label.setFont(label_font)
self.confirm_label.setFont(label_font)
# 将字体调小
label_font.setPixelSize(30)
self.cyberits_label.setFont(label_font)
def add_line_edit(self):
"""添加输入框"""
line_edit_font = QFont()
line_edit_font.setFamily('Consolas')
line_edit_font.setPixelSize(30)
# 创建三个输入框,父窗口为 self
self.username_edit = QLineEdit(self)
self.password_edit = QLineEdit(self)
self.confirm_edit = QLineEdit(self)
# 设置密码格式,输入密码的时候不可见密码
self.password_edit.setEchoMode(QLineEdit.Password)
self.confirm_edit.setEchoMode(QLineEdit.Password)
# 设置一下字体
self.username_edit.setFont(line_edit_font)
self.password_edit.setFont(line_edit_font)
self.confirm_edit.setFont(line_edit_font)
# 设置输入框中的占位符
self.username_edit.setPlaceholderText("username")
self.password_edit.setPlaceholderText("password")
self.confirm_edit.setPlaceholderText('password again')
# 控制大小
self.username_edit.setFixedSize(350, 40)
self.password_edit.setFixedSize(350, 40)
self.confirm_edit.setFixedSize(350, 40)
# 控制位置
self.username_edit.move(320, 530)
self.password_edit.move(320, 600)
self.confirm_edit.move(320, 670)
def add_button(self):
"""添加按钮"""
button_font = QFont()
button_font.setFamily('Consolas')
button_font.setPixelSize(30)
self.sign_button = QPushButton(self)
self.sign_button.setFixedSize(160, 50)
self.sign_button.setFont(button_font)
self.sign_button.move(750, 600)
self.sign_button.setText("Sign up")
self.sign_button.setShortcut('Return')
我们把它保存到另外一个文件Sign_Up.py
,如果我们要使用,调用该模块就可以了
逻辑关系
1. 注册
当用户输入账号密码的时候,我们首先获取用户的输入
username = self.username_edit.text()
password = self.password_edit.text()
confirm = self.confirm_edit.text()
然后对输入进行判断,首先应该判断是否为空,如果为空,提示输入,如果不为空,再检查是否存在该用户,如果没有在检查两次输入的密码是否一致,如果一致,写入数据库,如果不是提示密码不一致
if not password or not confirm: # 如果有一个密码或者密码确认框为空
QMessageBox.information(self, 'Error', 'The password is empty', QMessageBox.Yes)
elif self.is_has(username): # 如果用户名已经存在
QMessageBox.information(self, 'Error', 'The username already exists', QMessageBox.Yes)
else:
if password == confirm and password: # 如果两次密码一致,并且不为空
connect = sqlite3.connect('./data.db')
cursor = connect.cursor()
sql = 'INSERT INTO data (username, password) VALUES(?,?)' # 添加入数据库
cursor.execute(sql, (username, password))
connect.commit()
cursor.close()
connect.close()
QMessageBox.information(self, 'Successfully', 'Sign up successfully'.format(username),
QMessageBox.Yes)
self.close() # 注册完毕之后关闭窗口
else:
QMessageBox.information(self, 'Error', 'The password is not equal', QMessageBox.Yes)
数据库的操作可以看看我的另一篇 文章 操作
其中的is_has
代码如下:
@staticmethod
def is_has(username):
"""判断数据库中是否含有用户名"""
connect = sqlite3.connect('./data.db')
cursor = connect.cursor()
sql = 'SELECT * FROM data WHERE username=?'
result = cursor.execute(sql, (username,)) # 执行sqlite语句
connect.commit()
data = result.fetchall() # 获取所有的内容
cursor.close()
connect.close()
if data:
return True
else:
return False
代码中的QMessageBox
是PyQt5中提供的与用户进行交互的信息窗口,information
只是其中的一个,另外还有question
, warning
, critical
,使用方法一样,所接受的参数如下
QMessageBox.information(self, QWidget,p_str, p_str_1, buttons, QMessageBox_StandardButtons=None, QMessageBox_StandardButton=None, *args, **kwargs)
QWidget
-> 承载窗口
p_str
-> 标题
p_str_1
-> 提示文本
buttons
-> 弹窗的按钮,比如Ok, Cancel等
QMessageBox_StandardButtons
等 -> 为默认的按钮
实际上使用的时候参数对应可能有所不同
,比如对应的参数不会是p_str
另外当该窗口关闭的同时,我们应该将输入框中的文本清空,以免对下一次的输入造成影响,读者也可以自己试试 关闭窗口后清空输入框,只要重写关闭事件[6]方法便可以了,代码如下:
def closeEvent(self, event):
"""关闭之后将输入框清空"""
self.username_edit.setText('')
self.confirm_edit.setText('')
self.password_edit.setText('')
2. 登录
实现了注册功能之后,实现登录功能就很简单了,我们只需要从数据库中查找对应的用户数据,如果没有查找到,则提示用户不存在,否则判断密码是否正确,正确的话则登录成功,不正确提示密码错误
def login(self):
"""登录功能"""
connect = sqlite3.connect('./data.db') # 链接数据库
cursor = connect.cursor()
username = self.username_edit.text() # 获取账号
password = self.password_edit.text() # 获取密码
sql = 'SELECT username, password FROM data WHERE username=?' # 从数据库中读取数据
result = cursor.execute(sql, (username,))
data = result.fetchall()
if username and password: # 如果两个都不空
if data:
if str(data[0][1]) == password:
QMessageBox.information(self, 'Successfully', 'Login in successful \n Welcome {}'.format(username),
QMessageBox.Yes | QMessageBox.No)
else:
QMessageBox.information(self, 'Failed', 'Password is wrong, try again',
QMessageBox.Yes | QMessageBox.No)
else:
QMessageBox.information(self, 'Error', 'No such username', QMessageBox.Yes | QMessageBox.No)
elif username: # 如果用户名填了
QMessageBox.information(self, 'Error', 'Input your password', QMessageBox.Yes | QMessageBox.No)
else:
QMessageBox.information(self, 'Error', 'Fill in the blank', QMessageBox.Yes | QMessageBox.No)
经过上面的操作,我们终于完成了登录,注册界面的设置,以及相关逻辑功能的实现,但是其实上面的很多代码都是比较冗余的,有兴趣的小伙伴可以再修改修改。
在公众号Cyberist
中提供源码, 回复PyQt登录界面
即可获取下载地址
在之后会在该代码的基础之上添加更多的功能,并且使其更加结构化