我与PyQt5有个约会系列教程(11):神奇的登录界面小程序

写在最前面

上节课,我们介绍了对话框等知识点的大体概括,相信大家已经掌握的差不多了。

接下来呢,我们综合以前章节所学,来综合运用,写一个登录界面小程序。

登陆界面是大家常用的一种习惯方式,例如QQ、微信、淘宝、支付宝、网银、美团、京东、饿了么等等,耳详能熟的软件或者网站,你都能看登陆界面,各式各样,五花八门,但他们都具备一个共同特点,就是保护个人隐私信息。所以别看登陆界面简单不咋地,却有很大的学问。接下来,就让我们来研究一下登陆界面。

好的,那我们开始吧。

目录

第一步,登录界面布局

第二步,完善单行文本输入框和按钮功能

第三步,完善注册界面布局及功能

第四步,整合登录界面和注册界面

最后一步,小结

 

第一步,登录界面布局

首先完成登录界面布局,请看下方代码:

# -*- coding: utf-8 -*-

#--------------------------------------------------------------------------------
# 导入相关的包
#--------------------------------------------------------------------------------
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QPushButton, \
    QGridLayout, QVBoxLayout, QHBoxLayout
from PyQt5.QtGui import QIcon


class Example(QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()
    
    def initUI(self):   
        #------------------------------------------------------------------------------
        # 界面窗口标题、图标、大小
        #------------------------------------------------------------------------------
        self.setWindowTitle('我与PyQt5有个约会 -- 登陆界面')
        self.setWindowIcon(QIcon("myico.ico"))
        self.setGeometry(600,300,520,200)
        
        #------------------------------------------------------------------------------
        # 增添控件
        #------------------------------------------------------------------------------ 
        self.user_label = QLabel('用户名:', self)
        self.pwd_label = QLabel('密   码:', self)
        self.user_line = QLineEdit(self)
        self.pwd_line = QLineEdit(self)
        self.login_button = QPushButton('登录', self)
        self.signin_button = QPushButton('注册', self)
        
        #------------------------------------------------------------------------------
        # 布局
        #------------------------------------------------------------------------------ 
        self.grid_layout = QGridLayout()
        self.h_layout = QHBoxLayout()
        self.v_layout = QVBoxLayout()
 
        self.layout_init()
 
    def layout_init(self):
        self.grid_layout.addWidget(self.user_label, 0, 0, 1, 1)
        self.grid_layout.addWidget(self.user_line, 0, 1, 1, 1)
        self.grid_layout.addWidget(self.pwd_label, 1, 0, 1, 1)
        self.grid_layout.addWidget(self.pwd_line, 1, 1, 1, 1)
        self.h_layout.addWidget(self.login_button)
        self.h_layout.addWidget(self.signin_button)
        self.v_layout.addLayout(self.grid_layout)
        self.v_layout.addLayout(self.h_layout)
 
        self.setLayout(self.v_layout)
 
 
if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Example()
    demo.show()
    sys.exit(app.exec_())

程序首先将窗口的宽设为520,长设为200。

接着再实例化了几个控件:两个文本标签、两个单行文本输入框和两个按钮。

然后搭配使用网格布局管理器、水平布局管理器和垂直布局管理器来完成整个界面的布局。

这里有一点需要注意一下,我把布局管理专门放在了一个函数中layout_init(),然后只用在初始化函数中加上layout_init()中就行。把对不同控件的操作分开来放在相应的函数中,这样写不仅可以让代码更加清晰明了,也方便日后维护。

此时程序运行截图如下:

我与PyQt5有个约会系列教程(11):神奇的登录界面小程序_第1张图片

第二步,完善单行文本输入框和按钮功能 

第二步要完成的结果截图如下:

我与PyQt5有个约会系列教程(11):神奇的登录界面小程序_第2张图片

单行文本输入框中有浅灰色的提示文字,登录按钮刚开始无法点击,只能等两个输入框中都有文本输入的时候才可以进行点击。

所以呢,首先对输入框功能进行完善。 

#------------------------------------------------------------------------------
# 可编辑文本控件与事件绑定, 对输入框功能进行完善
#------------------------------------------------------------------------------
def line_edit_init(self):
    self.userQLineEdit.setPlaceholderText('请输入用户名')
    self.pwdQLineEdit.setPlaceholderText('请输入密码')
     
    self.userQLineEdit.textChanged.connect(self.check_input_func)
    self.pwdQLineEdit.textChanged.connect(self.check_input_func)

在未输入前,我们有会看到输入框上就已经有了一行浅灰色的提示文字。

就像下面这样子:

这种功能就是通过setPlaceholderText()方法来实现的。

在这里还进行了信号和槽的连接,将QLineEdit的textChanged()信号连接到一个自定义的槽self.check_input_func上。

textChanged()信号会在输入框中文本发生变化的时候发出, 所以槽函数的任务就是判断两个输入框是否都有文字了:
 

#------------------------------------------------------------------------------
# 登录按钮有效或者无效的判断
#------------------------------------------------------------------------------ 
def check_input_func(self):
    if self.userQLineEdit.text() and self.pwdQLineEdit.text():
        self.loginQPushButton.setEnabled(True)
    else:
        self.loginQPushButton.setEnabled(False)

 如果用户框和密码框都有文本(通过text()方法获取输入框文本),那就使登录按钮可用(setEnabled(True)),否则登录按钮不可用。

接下来对按钮进行完善:

#------------------------------------------------------------------------------
# 按钮控件与事件绑定
#------------------------------------------------------------------------------
def qpushbutton_init(self):
    self.loginQPushButton.setEnabled(False)

使刚开始显示的登录按钮不可用,只有等账号框和密码框都有文本的时候才能用。

当我们点击登录按钮的时候,账号框和密码框都有文本了。

那点击后肯定是要验证账号密码是否正确:

#------------------------------------------------------------------------------
# 按钮控件与事件绑定
#------------------------------------------------------------------------------
def qpushbutton_init(self):
    self.loginQPushButton.clicked.connect(self.check_login_func)
    self.loginQPushButton.setEnabled(False)

所以我们将登录按钮的clicked信号和一个用于检查账号密码是否正确的自定义槽函数连接起来:

首先我们在程序的最开始处定义一个全局变量USER_PWD:

#------------------------------------------------------------------------------
# 全局变量
#------------------------------------------------------------------------------
USER_PWD = {'root':'123456'}

该字典的键'root'就是当作账号,值‘123456’就当作密码。

然后定义检查账号密码的函数:

#------------------------------------------------------------------------------
# 登录功能的验证
#------------------------------------------------------------------------------
def check_login_func(self):
    if USER_PWD.get(self.userQLineEdit.text()) == self.pwdQLineEdit.text():
        QMessageBox.information(self, '提示', '登陆成功!')
    else:
        QMessageBox.critical(self, '错误提示', '用户名或者密码错误!')
     
    self.userQLineEdit.clear()
    self.pwdQLineEdit.clear()

将账号框的文本当作get()的参数来获取值,然后跟密码框的文本进行比较,若相同则显示信息框提示登录成功,否则显示账号或密码错误。最后无论成功还是失败,都会用clear()方法来清空账号框和密码框。

第二步基本实现的程序功能效果展示如下:

我与PyQt5有个约会系列教程(11):神奇的登录界面小程序_第3张图片

源代码参考如下:

# -*- coding: utf-8 -*-

#--------------------------------------------------------------------------------
# 导入相关的包
#--------------------------------------------------------------------------------
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QPushButton, \
    QGridLayout, QVBoxLayout, QHBoxLayout, QMessageBox
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import *

#------------------------------------------------------------------------------
# 全局变量
#------------------------------------------------------------------------------
USER_PWD = {'root':'123456'}

class Example(QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()
    
    def initUI(self):   
        #------------------------------------------------------------------------------
        # 界面窗口标题、图标、大小
        #------------------------------------------------------------------------------
        self.setWindowTitle('我与PyQt5有个约会 -- 登陆界面')
        self.setWindowIcon(QIcon("myico.ico"))
        self.setGeometry(600,300,520,200)
        
        #------------------------------------------------------------------------------
        # 增添控件
        #------------------------------------------------------------------------------ 
        self.userQLabel = QLabel('用户名:', self)
        self.pwdQLabel = QLabel('密   码:', self)
        self.userQLineEdit = QLineEdit(self)
        self.pwdQLineEdit = QLineEdit(self)
        self.loginQPushButton = QPushButton('登录', self)
        self.signinQPushButton = QPushButton('注册', self)
        
        #------------------------------------------------------------------------------
        # 布局
        #------------------------------------------------------------------------------ 
        self.grid_layout = QGridLayout()
        self.h_layout = QHBoxLayout()
        self.v_layout = QVBoxLayout()
        
        #------------------------------------------------------------------------------
        # 功能函数的调用
        #------------------------------------------------------------------------------ 
        self.line_edit_init()
        self.qpushbutton_init()
        self.layout_init()
    
    #------------------------------------------------------------------------------
    # 布局安排
    #------------------------------------------------------------------------------
    def layout_init(self):
        self.grid_layout.addWidget(self.userQLabel, 0, 0, 1, 1)
        self.grid_layout.addWidget(self.userQLineEdit, 0, 1, 1, 1)
        self.grid_layout.addWidget(self.pwdQLabel, 1, 0, 1, 1)
        self.grid_layout.addWidget(self.pwdQLineEdit, 1, 1, 1, 1)
        self.h_layout.addWidget(self.loginQPushButton)
        self.h_layout.addWidget(self.signinQPushButton)
        self.v_layout.addLayout(self.grid_layout)
        self.v_layout.addLayout(self.h_layout)
 
        self.setLayout(self.v_layout)

    #------------------------------------------------------------------------------
    # 可编辑文本控件与事件绑定, 对输入框功能进行完善
    #------------------------------------------------------------------------------
    def line_edit_init(self):
        self.userQLineEdit.setPlaceholderText('请输入用户名')
        self.pwdQLineEdit.setPlaceholderText('请输入密码')
     
        self.userQLineEdit.textChanged.connect(self.check_input_func)
        self.pwdQLineEdit.textChanged.connect(self.check_input_func)
        
    #------------------------------------------------------------------------------
    # 登录按钮有效或者无效的判断
    #------------------------------------------------------------------------------ 
    def check_input_func(self):
        if self.userQLineEdit.text() and self.pwdQLineEdit.text():
            self.loginQPushButton.setEnabled(True)
        else:
            self.loginQPushButton.setEnabled(False)
        
    #------------------------------------------------------------------------------
    # 按钮控件与事件绑定
    #------------------------------------------------------------------------------
    def qpushbutton_init(self):
        print('self.loginQPushButton.clicked.connect(self.check_login_func)')
        self.loginQPushButton.clicked.connect(self.check_login_func)
        self.loginQPushButton.setEnabled(False)
        
    #------------------------------------------------------------------------------
    # 登录功能的验证
    #------------------------------------------------------------------------------
    def check_login_func(self):
        if USER_PWD.get(self.userQLineEdit.text()) == self.pwdQLineEdit.text():
            QMessageBox.information(self, '提示', '登陆成功!')
        else:
            QMessageBox.critical(self, '错误提示', '用户名或者密码错误!')
     
        self.userQLineEdit.clear()
        self.pwdQLineEdit.clear()

#------------------------------------------------------------------------------
# 登录功能的验证
#------------------------------------------------------------------------------
if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Example()
    demo.show()
    sys.exit(app.exec_())

第三步,完善注册界面布局及功能

接下来就是要完善注册按钮这个功能,这里我们想的是点击这个按钮后,会出现一个新的界面用于注册,即下方截图所示: 

我与PyQt5有个约会系列教程(11):神奇的登录界面小程序_第4张图片

可以看出该界面一共是由三个QLabel、三个QLineEdit和一个QPushButton组成的,那首先就来完成界面布局:

# -*- coding: utf-8 -*-

#--------------------------------------------------------------------------------
# 导入相关的包
#--------------------------------------------------------------------------------
import sys
from PyQt5.QtWidgets import QApplication, QLabel, QLineEdit, QPushButton, \
    QGridLayout, QVBoxLayout, QHBoxLayout, QDialog
from PyQt5.QtGui import QIcon


class SigninPage(QDialog):
    def __init__(self):
        super(SigninPage, self).__init__()
        self.initUI()
    
    def initUI(self):  
        #------------------------------------------------------------------------------
        # 界面窗口标题、图标、大小
        #------------------------------------------------------------------------------      
        self.setWindowTitle('我与PyQt5有个约会 -- 注册界面')
        self.setWindowIcon(QIcon("myico.ico"))
        self.setGeometry(600,300,450,200)
        
        #------------------------------------------------------------------------------
        # 增添控件
        #------------------------------------------------------------------------------         
        self.signinUserQLabel = QLabel('用户名:', self)
        self.signinPwdQLabel = QLabel('输入密码:', self)
        self.signinPwd2QLabel = QLabel('再次输入密码:', self)
        self.signinUserQLineEdit = QLineEdit(self)
        self.signinPwdQLineEdit = QLineEdit(self)
        self.signinPwd2QLineEdit = QLineEdit(self)
        self.signinQPushButton = QPushButton('注册', self)
        
        #------------------------------------------------------------------------------
        # 布局
        #------------------------------------------------------------------------------ 
        self.grid_layout = QGridLayout()
        self.all_v_layout = QVBoxLayout()
 
        self.layout_init()
        
    #------------------------------------------------------------------------------
    # 布局安排
    #------------------------------------------------------------------------------
    def layout_init(self):
        self.grid_layout.addWidget(self.signinUserQLabel, 0, 0, 1, 1)
        self.grid_layout.addWidget(self.signinUserQLineEdit, 0, 1, 1, 1)
        self.grid_layout.addWidget(self.signinPwdQLabel, 1, 0, 1, 1)
        self.grid_layout.addWidget(self.signinPwdQLineEdit, 1, 1, 1, 1)
        self.grid_layout.addWidget(self.signinPwd2QLabel, 2, 0, 1, 1)
        self.grid_layout.addWidget(self.signinPwd2QLineEdit, 2, 1, 1, 1)
 
        self.all_v_layout.addLayout(self.grid_layout)
        self.all_v_layout.addWidget(self.signinQPushButton)
 
        self.setLayout(self.all_v_layout)

#------------------------------------------------------------------------------
# 登录功能的验证֤
#------------------------------------------------------------------------------
if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = SigninPage()
    demo.show()
    sys.exit(app.exec_())

这里新写一个类,并继承于QDialog。

QDialog就是指对话框,我们平时在软件中点击“打开”或“另存为”而出现的文件对话框就是其中一种。

首先,同样将注册按钮设为不可用(setEnabled(False)),并且只有当三个输入框中都有文本的时候,才会启用这个按钮。原理跟之前讲的一样:

#------------------------------------------------------------------------------
# 可编辑文本控件与事件绑定, 对输入框功能进行完善
#------------------------------------------------------------------------------   
def line_edit_init(self):
    self.signinUserQLineEdit.setPlaceholderText('请输入用户名')
    self.signinPwdQLineEdit.setPlaceholderText('请输入密码')
    self.signinPwd2QLineEdit.setPlaceholderText('请再次输入密码')

    self.signinUserQLineEdit.textChanged.connect(self.check_input_func)
    self.signinPwdQLineEdit.textChanged.connect(self.check_input_func)
    self.signinPwd2QLineEdit.textChanged.connect(self.check_input_func)

在line_edit_init()中我们将三个输入框的textChanged()信号跟自定义的check_input_func()槽函数进行连接;

#------------------------------------------------------------------------------
# 登录按钮有效或者无效的判断
#------------------------------------------------------------------------------ 
def check_input_func(self):
    if self.userQLineEdit.text() and self.pwdQLineEdit.text():
        self.loginQPushButton.setEnabled(True)
    else:
        self.loginQPushButton.setEnabled(False)

在槽函数中我们判断三个输入框是否都有文本,有的话则将按钮启用,否则禁用;

#------------------------------------------------------------------------------
# 按钮控件与事件绑定
#------------------------------------------------------------------------------            
def qpushbutton_init(self):
    self.signinQPushButton.setEnabled(False)
    self.signinQPushButton.clicked.connect(self.check_signin_func)

然后在qpushbutton_init()中先将注册按钮设为禁用状态,然后将clicked()信号和之后自定义的check_signin_func()槽函数连接起来。因为在点击注册按钮的时候我们要对输入的文本内容进行检查,看符不符合要求;

#------------------------------------------------------------------------------
# 注册功能的实现
#------------------------------------------------------------------------------
def check_signin_func(self):
    if self.signinPwdQLineEdit.text() != self.signinPwd2QLineEdit.text():
        QMessageBox.critical(self, '错误', '两次输入的密码不一致!请重新输入......')
    elif self.signinUserQLineEdit.text() not in USER_PWD:
        USER_PWD[self.signinUserQLineEdit.text()] = self.signinPwdQLineEdit.text()
        QMessageBox.information(self, '通知', '注册成功!')
        self.close()
    else:
        QMessageBox.critical(self, '错误', '该用户名已经被注册过了!')
     
    self.signinUserQLineEdit.clear()
    self.signinPwdQLineEdit.clear()
    self.signinPwd2QLineEdit.clear()

首先判断两次密码输入框输入的文本是否一致,若不相同的话,则显示错误框提示;

当然我们还要对要注册的账号进行判断,如果在字典相对应的键,则说明该账号并没有被注册过,接着将要注册的账号和密码放进字典中,并显示信息框提示注册成功。

self.close()是指关闭对话框自身,也就是在信息框按钮被按下去关闭之后,注册界面的对话框也要一起关闭。

最后一种情况就是账号已经被注册过了,于是显示错误框来进行提示。

无论哪种情况,最后都会将三个输入框的文本清空掉。

最终的效果如下:

那么最后将self.lineedit_init()和self.qpushbutton_init()放在类的初始化函数__init__()中。

源代码如下:

# -*- coding: utf-8 -*-

#--------------------------------------------------------------------------------
# 导入相关的包
#--------------------------------------------------------------------------------
import sys
from PyQt5.QtWidgets import QApplication, QLabel, QLineEdit, QPushButton, \
    QGridLayout, QVBoxLayout, QDialog, QMessageBox
from PyQt5.QtGui import QIcon

#------------------------------------------------------------------------------
# 全局变量
#------------------------------------------------------------------------------
USER_PWD = {'root':'123456'}

class SigninPage(QDialog):
    def __init__(self):
        super(SigninPage, self).__init__()
        self.initUI()
    
    def initUI(self):  
        #------------------------------------------------------------------------------
        # 界面窗口标题、图标、大小
        #------------------------------------------------------------------------------      
        self.setWindowTitle('我与PyQt5有个约会 -- 注册界面')
        self.setWindowIcon(QIcon("myico.ico"))
        self.setGeometry(600,300,450,200)
        
        #------------------------------------------------------------------------------
        # 增添控件
        #------------------------------------------------------------------------------         
        self.signinUserQLabel = QLabel('用户名:', self)
        self.signinPwdQLabel = QLabel('输入密码:', self)
        self.signinPwd2QLabel = QLabel('再次输入密码:', self)
        self.signinUserQLineEdit = QLineEdit(self)
        self.signinPwdQLineEdit = QLineEdit(self)
        self.signinPwd2QLineEdit = QLineEdit(self)
        self.signinQPushButton = QPushButton('注册', self)
        
        #------------------------------------------------------------------------------
        # 布局
        #------------------------------------------------------------------------------ 
        self.grid_layout = QGridLayout()
        self.all_v_layout = QVBoxLayout()
        
        #------------------------------------------------------------------------------
        # 功能函数的调用
        #------------------------------------------------------------------------------ 
        self.line_edit_init()
        self.qpushbutton_init()
        self.layout_init()
        
    #------------------------------------------------------------------------------
    # 布局安排
    #------------------------------------------------------------------------------
    def layout_init(self):
        self.grid_layout.addWidget(self.signinUserQLabel, 0, 0, 1, 1)
        self.grid_layout.addWidget(self.signinUserQLineEdit, 0, 1, 1, 1)
        self.grid_layout.addWidget(self.signinPwdQLabel, 1, 0, 1, 1)
        self.grid_layout.addWidget(self.signinPwdQLineEdit, 1, 1, 1, 1)
        self.grid_layout.addWidget(self.signinPwd2QLabel, 2, 0, 1, 1)
        self.grid_layout.addWidget(self.signinPwd2QLineEdit, 2, 1, 1, 1)
 
        self.all_v_layout.addLayout(self.grid_layout)
        self.all_v_layout.addWidget(self.signinQPushButton)
 
        self.setLayout(self.all_v_layout)
 
    #------------------------------------------------------------------------------
    # 可编辑文本控件与事件绑定, 对输入框功能进行完善
    #------------------------------------------------------------------------------   
    def line_edit_init(self):
        self.signinUserQLineEdit.setPlaceholderText('请输入用户名')
        self.signinPwdQLineEdit.setPlaceholderText('请输入密码')
        self.signinPwd2QLineEdit.setPlaceholderText('请再次输入密码')
        
        self.signinUserQLineEdit.textChanged.connect(self.check_input_func)
        self.signinPwdQLineEdit.textChanged.connect(self.check_input_func)
        self.signinPwd2QLineEdit.textChanged.connect(self.check_input_func)
        
    #------------------------------------------------------------------------------
    # 登录按钮有效或者无效的判断
    #------------------------------------------------------------------------------
    def check_input_func(self):
        if self.signinUserQLineEdit.text() and self.signinPwdQLineEdit.text() and self.signinPwd2QLineEdit.text():
            self.signinQPushButton.setEnabled(True)
        else:
            self.signinQPushButton.setEnabled(False)
            
    #------------------------------------------------------------------------------
    # 按钮控件与事件绑定
    #------------------------------------------------------------------------------            
    def qpushbutton_init(self):
        self.signinQPushButton.setEnabled(False)
        self.signinQPushButton.clicked.connect(self.check_signin_func)
        
    #------------------------------------------------------------------------------
    # 注册功能的实现
    #------------------------------------------------------------------------------
    def check_signin_func(self):
        if self.signinPwdQLineEdit.text() != self.signinPwd2QLineEdit.text():
            QMessageBox.critical(self, '错误', '两次输入的密码不一致!请重新输入......')
        elif self.signinUserQLineEdit.text() not in USER_PWD:
            USER_PWD[self.signinUserQLineEdit.text()] = self.signinPwdQLineEdit.text()
            QMessageBox.information(self, '通知', '注册成功!')
            self.close()
        else:
            QMessageBox.critical(self, '错误', '该用户名已经被注册过了!')
     
        self.signinUserQLineEdit.clear()
        self.signinPwdQLineEdit.clear()
        self.signinPwd2QLineEdit.clear()

#------------------------------------------------------------------------------
# 登录功能的验证֤
#------------------------------------------------------------------------------
if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = SigninPage()
    demo.show()
    sys.exit(app.exec_())

第四步,整合登录界面和注册界面

但是此时运行程序点击登录界面上的注册按钮的话,注册界面是显示不出来的,所以我们要将登录界面注册按钮的clicked()信号和一个自定义的用来显示注册界面的槽函数连接起来: 

    def initUI(self):   
        #------------------------------------------------------------------------------
        # 界面窗口标题、图标、大小
        #------------------------------------------------------------------------------
        self.setWindowTitle('我与PyQt5有个约会 -- 登陆界面')
        self.setWindowIcon(QIcon("myico.ico"))
        self.setGeometry(600,300,520,200)
        
        #------------------------------------------------------------------------------
        # 增添控件
        #------------------------------------------------------------------------------ 
        self.userQLabel = QLabel('用户名:', self)
        self.pwdQLabel = QLabel('密   码:', self)
        self.userQLineEdit = QLineEdit(self)
        self.pwdQLineEdit = QLineEdit(self)
        self.loginQPushButton = QPushButton('登录', self)
        self.signinQPushButton = QPushButton('注册', self)
        
        #------------------------------------------------------------------------------
        # 布局
        #------------------------------------------------------------------------------ 
        self.grid_layout = QGridLayout()
        self.h_layout = QHBoxLayout()
        self.v_layout = QVBoxLayout()
        
        #------------------------------------------------------------------------------
        # 功能函数的调用
        #------------------------------------------------------------------------------ 
        self.line_edit_init()
        self.qpushbutton_init()
        self.layout_init()
        
        self.signin_page = SigninPage()     # 实例化SigninPage()

首先我们在Example的初始化函数中先实例化了SigninPage;

#------------------------------------------------------------------------------
# 按钮控件与事件绑定
#------------------------------------------------------------------------------
def qpushbutton_init(self):
    self.loginQPushButton.setEnabled(False) 
    self.loginQPushButton.clicked.connect(self.check_login_func)   
    self.signinQPushButton.clicked.connect(self.show_signin_page_func)

接着在处理按钮的函数中将注册按钮的clicked信号和show_signin_page_func()槽函数进行连接;

#------------------------------------------------------------------------------
# 处理按钮的函数中将注册按钮的clicked信号和show_signin_page_func()槽函数进行绑定
#------------------------------------------------------------------------------
def show_signin_page_func(self):
    self.signin_page.exec_()

在槽函数中,我们用exec_方法来执行注册界面。为什么要使用exec_而不是show()?下面来详细解释下这两个方法的区别:

若使用exec_()的话,那么显示出来的注册界面就是模态的,意思就是当前只能对该注册界面进行操作,只有关闭了该界面才能对其他界面进行操作;若使用show()的话,那注册界面就是非模态的,则在显示了注册界面后,还能同时对登录界面进行操作(QDialog有exec_()方法,而QWidget没有)。

运行软件,功能展示效果如下:

 

上面为了方便演示,所以密码框输入的时候都没有用原点替代,我们可以对输入框使用setEchoMode(QLineEdit.Password)方法来完成此功能。

效果如下:

最终完整的源代码如下所示:

# -*- coding: utf-8 -*-

#--------------------------------------------------------------------------------
# 导入相关的包
#--------------------------------------------------------------------------------
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QPushButton, \
    QGridLayout, QVBoxLayout, QHBoxLayout, QMessageBox, QDialog
from PyQt5.QtGui import QIcon

#------------------------------------------------------------------------------
# 全局变量
#------------------------------------------------------------------------------
USER_PWD = {'root':'123456'}

#------------------------------------------------------------------------------
# 注册界面
#------------------------------------------------------------------------------
class SigninPage(QDialog):
    def __init__(self):
        super(SigninPage, self).__init__()
        self.initUI()
    
    def initUI(self):  
        #------------------------------------------------------------------------------
        # 界面窗口标题、图标、大小
        #------------------------------------------------------------------------------      
        self.setWindowTitle('我与PyQt5有个约会 -- 注册界面')
        self.setWindowIcon(QIcon("myico.ico"))
        self.setGeometry(600,300,450,200)
        
        #------------------------------------------------------------------------------
        # 增添控件
        #------------------------------------------------------------------------------         
        self.signinUserQLabel = QLabel('用户名:', self)
        self.signinPwdQLabel = QLabel('输入密码:', self)
        self.signinPwd2QLabel = QLabel('再次输入密码:', self)
        self.signinUserQLineEdit = QLineEdit(self)
        self.signinPwdQLineEdit = QLineEdit(self)
        self.signinPwdQLineEdit.setEchoMode(QLineEdit.Password)
        self.signinPwd2QLineEdit = QLineEdit(self)
        self.signinPwd2QLineEdit.setEchoMode(QLineEdit.Password)
        self.signinQPushButton = QPushButton('注册', self)
        
        #------------------------------------------------------------------------------
        # 布局
        #------------------------------------------------------------------------------ 
        self.grid_layout = QGridLayout()
        self.all_v_layout = QVBoxLayout()
        
        #------------------------------------------------------------------------------
        # 功能函数的调用
        #------------------------------------------------------------------------------ 
        self.line_edit_init()
        self.qpushbutton_init()
        self.layout_init()  
        
    #------------------------------------------------------------------------------
    # 布局安排
    #------------------------------------------------------------------------------
    def layout_init(self):
        self.grid_layout.addWidget(self.signinUserQLabel, 0, 0, 1, 1)
        self.grid_layout.addWidget(self.signinUserQLineEdit, 0, 1, 1, 1)
        self.grid_layout.addWidget(self.signinPwdQLabel, 1, 0, 1, 1)
        self.grid_layout.addWidget(self.signinPwdQLineEdit, 1, 1, 1, 1)
        self.grid_layout.addWidget(self.signinPwd2QLabel, 2, 0, 1, 1)
        self.grid_layout.addWidget(self.signinPwd2QLineEdit, 2, 1, 1, 1)
 
        self.all_v_layout.addLayout(self.grid_layout)
        self.all_v_layout.addWidget(self.signinQPushButton)
 
        self.setLayout(self.all_v_layout)
 
    #------------------------------------------------------------------------------
    # 可编辑文本控件与事件绑定, 对输入框功能进行完善
    #------------------------------------------------------------------------------   
    def line_edit_init(self):
        self.signinUserQLineEdit.setPlaceholderText('请输入用户名')
        self.signinPwdQLineEdit.setPlaceholderText('请输入密码')
        self.signinPwd2QLineEdit.setPlaceholderText('请再次输入密码')
        
        self.signinUserQLineEdit.textChanged.connect(self.check_input_func)
        self.signinPwdQLineEdit.textChanged.connect(self.check_input_func)
        self.signinPwd2QLineEdit.textChanged.connect(self.check_input_func)
        
    #------------------------------------------------------------------------------
    # 登录按钮有效或者无效的判断
    #------------------------------------------------------------------------------
    def check_input_func(self):
        if self.signinUserQLineEdit.text() and self.signinPwdQLineEdit.text() and self.signinPwd2QLineEdit.text():
            self.signinQPushButton.setEnabled(True)
        else:
            self.signinQPushButton.setEnabled(False)
            
    #------------------------------------------------------------------------------
    # 按钮控件与事件绑定
    #------------------------------------------------------------------------------            
    def qpushbutton_init(self):
        self.signinQPushButton.setEnabled(False)
        self.signinQPushButton.clicked.connect(self.check_signin_func)
        
    #------------------------------------------------------------------------------
    # 注册功能的实现
    #------------------------------------------------------------------------------
    def check_signin_func(self):
        if self.signinPwdQLineEdit.text() != self.signinPwd2QLineEdit.text():
            QMessageBox.critical(self, '错误', '两次输入的密码不一致!请重新输入......')
        elif self.signinUserQLineEdit.text() not in USER_PWD:
            USER_PWD[self.signinUserQLineEdit.text()] = self.signinPwdQLineEdit.text()
            QMessageBox.information(self, '通知', '注册成功!')
            self.close()
        else:
            QMessageBox.critical(self, '错误', '该用户名已经被注册过了!')
     
        self.signinUserQLineEdit.clear()
        self.signinPwdQLineEdit.clear()
        self.signinPwd2QLineEdit.clear()



class Example(QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()
    
    def initUI(self):   
        #------------------------------------------------------------------------------
        # 界面窗口标题、图标、大小
        #------------------------------------------------------------------------------
        self.setWindowTitle('我与PyQt5有个约会 -- 登陆界面')
        self.setWindowIcon(QIcon("myico.ico"))
        self.setGeometry(600,300,520,200)
        
        #------------------------------------------------------------------------------
        # 增添控件
        #------------------------------------------------------------------------------ 
        self.userQLabel = QLabel('用户名:', self)
        self.pwdQLabel = QLabel('密   码:', self)
        self.userQLineEdit = QLineEdit(self)
        self.pwdQLineEdit = QLineEdit(self)
        self.pwdQLineEdit.setEchoMode(QLineEdit.Password)
        self.loginQPushButton = QPushButton('登录', self)
        self.signinQPushButton = QPushButton('注册', self)
        
        #------------------------------------------------------------------------------
        # 布局
        #------------------------------------------------------------------------------ 
        self.grid_layout = QGridLayout()
        self.h_layout = QHBoxLayout()
        self.v_layout = QVBoxLayout()
        
        #------------------------------------------------------------------------------
        # 功能函数的调用
        #------------------------------------------------------------------------------ 
        self.line_edit_init()
        self.qpushbutton_init()
        self.layout_init()
        
        self.signin_page = SigninPage()     # 实例化SigninPage()
    #------------------------------------------------------------------------------
    # 布局安排
    #------------------------------------------------------------------------------
    def layout_init(self):
        self.grid_layout.addWidget(self.userQLabel, 0, 0, 1, 1)
        self.grid_layout.addWidget(self.userQLineEdit, 0, 1, 1, 1)
        self.grid_layout.addWidget(self.pwdQLabel, 1, 0, 1, 1)
        self.grid_layout.addWidget(self.pwdQLineEdit, 1, 1, 1, 1)
        self.h_layout.addWidget(self.loginQPushButton)
        self.h_layout.addWidget(self.signinQPushButton)
        self.v_layout.addLayout(self.grid_layout)
        self.v_layout.addLayout(self.h_layout)
 
        self.setLayout(self.v_layout)

    #------------------------------------------------------------------------------
    # 可编辑文本控件与事件绑定, 对输入框功能进行完善
    #------------------------------------------------------------------------------
    def line_edit_init(self):
        self.userQLineEdit.setPlaceholderText('请输入用户名')
        self.pwdQLineEdit.setPlaceholderText('请输入密码')
     
        self.userQLineEdit.textChanged.connect(self.check_input_func)
        self.pwdQLineEdit.textChanged.connect(self.check_input_func)
        
    #------------------------------------------------------------------------------
    # 登录按钮有效或者无效的判断
    #------------------------------------------------------------------------------ 
    def check_input_func(self):
        if self.userQLineEdit.text() and self.pwdQLineEdit.text():
            self.loginQPushButton.setEnabled(True)
        else:
            self.loginQPushButton.setEnabled(False)
        
    #------------------------------------------------------------------------------
    # 按钮控件与事件绑定
    #------------------------------------------------------------------------------
    def qpushbutton_init(self):
        self.loginQPushButton.setEnabled(False) 
        self.loginQPushButton.clicked.connect(self.check_login_func)   
        self.signinQPushButton.clicked.connect(self.show_signin_page_func)
        
    #------------------------------------------------------------------------------
    # 处理按钮的函数中将注册按钮的clicked信号和show_signin_page_func()槽函数进行绑定
    #------------------------------------------------------------------------------
    def show_signin_page_func(self):
        self.signin_page.exec_()
 
    #------------------------------------------------------------------------------
    # 登录功能的验证
    #------------------------------------------------------------------------------
    def check_login_func(self):
        if USER_PWD.get(self.userQLineEdit.text()) == self.pwdQLineEdit.text():
            QMessageBox.information(self, '提示', '登陆成功!')
        else:
            QMessageBox.critical(self, '错误提示', '用户名或者密码错误!')
     
        self.userQLineEdit.clear()
        self.pwdQLineEdit.clear()

#------------------------------------------------------------------------------
# 登录功能的验证
#------------------------------------------------------------------------------
if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Example()
    demo.show()
    sys.exit(app.exec_())

最后一步,小结

1. setPlaceholderText()方法用于在输入框显示浅灰色的提示文本;

2. exec_()方法可以让窗口成为模态窗口,而调用show()方法,窗口是非模态的。模态窗口将程序控制权占据,只有对当前窗口关闭后才能操作其他窗口;

3. QDialog有exec_()方法,而QWidget没有;

4. 可以用setEchoMode(QLineEdit.Password)将普通输入框中的文字变成原点,变成隐式的,看不到具体的。
 

这一节,就到这里吧,神奇的登录界面小程序,你学会了吗?

 

有志者,事竟成,破釜沉舟,百二秦关终属楚;

苦心人,天不负,卧薪尝胆,三千越甲可吞吴。

你可能感兴趣的:(PyQt5)