暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

PyQt实现界面化登录注册,并用数据库保存用户信息

Golang学习杂记 2019-11-27
1547

目录

1. 前言

2. 环境配置

  1. 下载安装 python

  2. 安装配置编辑器

  3. 下载所需库

3. 主页面

      3.1. 创建一个页面
      3.2. 添加相关控件
         3.2.1. 添加标签
         3.2.2. 添加输入框
         3.2.3. 添加按钮
         3.2.4. 设置背景

4. 注册页面

   界面设计

5. 逻辑关系

    5.1. 注册    
    5.2. 登录

前言

上一次利用tkinter
设计了一个登陆注册界面受到了很多小伙伴的关注(传送门[1]),于是想着利用PyQt
来实现,当然是因为 PyQt
长的好看呀
,并且这一次我们使用数据库
来存储用户信息,是不是一下子比上一次逼格了不少,我们先看看效果吧

那么我们下面马上开始吧!!


环境配置

  1. 下载安装 python[2]
  2. 安装配置编辑器[3]
  3. 下载所需库

前面的两个内容在之前的教程中已经解决了,接下来我们来下载安装所要使用的库, 只需要运行以下的命令便可以安装 PyQt5
了,不过时间可能稍微长一点,耐心等待~~

pip install PyQt5

主页面

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
    方法来显示窗口[②]
  • 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
对象,然后使用其中的方法[③]

setText
-> 设置文本内容
setFixedSize
-> 设置不可修改的窗口大小

然后我们来设置以下字体,利用 QFont
对象来创建一个字体对象,然后使用QLabel
对象的setFont
方法进行设置

 # 设置字体
label_font = QFont()
label_font.setFamily('Consolas')
label_font.setPixelSize(35)
self.label.setFont(label_font)
 

QFont
中的方法[③]

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
对象,并在其上设置一下背景图片,如果直接设置的话,可能不太好操作和理解,但是注意,在绘制中,首先绘制的会在窗口的后端,后绘制的会在前端,所以要先创建背景,然后在设置之前的效果,否则可能出现意想不到的效果[④],实现代码如下:

def set_background_image(self):
"""添加背景图片"""
self.frame = QFrame(self)
self.frame.resize(1000, 520)
self.frame.move(40, 150)
self.frame.setStyleSheet(
' background-repeat: no-repeat; text-align:center;')
        

首先创建一个QFrame
对象,然后控制其大小和位置,最后使用setStyleSheet
对其进行设置,其参数可以是类似css
样式的字符串,或者说是qss
[⑤]

到这里我们对主页面的外观设置已经完成了,样式如图(个人觉得比 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)

数据库的操作可以看看我的另一篇 文章[4] 操作 其中的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

另外当该窗口关闭的同时,我们应该将输入框中的文本清空,以免对下一次的输入造成影响,读者也可以自己试试 关闭窗口后清空输入框,只要重写关闭事件方法[⑥]便可以了,代码如下:

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[5]中提供源码, 回复PyQt登录界面
即可获取下载地址


注释

[①]:在作者写的代码中导入是逐个逐个导入的,这样对资源的消耗量小


[②]:因为它没有父窗口,如果有父窗口的话只需要调用父窗口的show方法


[③]:当然这只是其中众多方法的一部分,更多方法之后会有专栏进行讲解


[④]:比如输入框无法用鼠标点击,按钮无法用鼠标点击


[⑤]:更多内容在这里不详细介绍了,届时请关注专栏


[⑥]:PyQt5中提供了许多事件消息,该事件是窗口关闭之后执行的动作


相关链接

[1]

传送门: https://blog.csdn.net/weixin_44676081/article/details/103145416

[2]

下载安装 python: https://blog.csdn.net/weixin_44676081/article/details/102750062

[3]

安装配置编辑器: https://blog.csdn.net/weixin_44676081/article/details/102753089

[4]

文章: https://blog.csdn.net/weixin_44676081/article/details/103225032

[5]

公众号名片:https://blog.csdn.net/weixin_44676081/article/details/103267546


文章转载自Golang学习杂记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论