pyqt5 开发不规则用户界面(pyqt5登录界面设计模仿qq登录界面)
pyqt5 开发不规则用户界面(pyqt5登录界面设计模仿qq登录界面)假如我的原主界面函数如下: mainWnd.setFixedSize(QSize(650 500)) #因为这里固定了大小,所以窗口的大小没有办法任意调整,想要使resizeWidget函数生效的话要把这里去掉,自己调节布局和窗口大小 在511行 on_pushButton_enter_clicked函数中,实现了一个账号和密码判断的函数,如果输入正确,则销毁登录界面,login_main.py函数运行结束,可以进入到你的主界面。这里的账号名和密码你可以随便改动。pyqt5实现登录界面首先最开始,我们自己用代码编写了一个标题栏,用于美化我们的登录界面,但是这个和你主界面的并无关系。在代码190行第载入了一张图片,这个图片你可以随意改变。 palette1.setBrush(self.backgroundRole() QtGui.QBrush( Q
今天给大家分享一个十分不错的pyqt5实现的登录界面,很像qq的登录界面,你可以将此登录界面用到自己的项目中,甚至完全不用修改,只需在自己项目中运行该py文件即可,在输入正确的账号和密码后,就可以进入的自己的主界面。
效果图:登录界面示意图
视频效果图
西瓜视频地址:
pyqt5实现登录界面
代码说明首先最开始,我们自己用代码编写了一个标题栏,用于美化我们的登录界面,但是这个和你主界面的并无关系。在代码190行第载入了一张图片,这个图片你可以随意改变。
palette1.setBrush(self.backgroundRole() QtGui.QBrush(
QtGui.QPixmap('log0.jpg'))) # 设置登录背景图片
然后在536行,我们可以调整登录界面大小。
mainWnd.setFixedSize(QSize(650 500)) #因为这里固定了大小,所以窗口的大小没有办法任意调整,想要使resizeWidget函数生效的话要把这里去掉,自己调节布局和窗口大小
在511行 on_pushButton_enter_clicked函数中,实现了一个账号和密码判断的函数,如果输入正确,则销毁登录界面,login_main.py函数运行结束,可以进入到你的主界面。这里的账号名和密码你可以随便改动。
使用示例假如我的原主界面函数如下:
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
想加入登录界面,只需要在第二行直接插入
os.system('python login_main.py') #执行login_main.py文件
即
app = QtWidgets.QApplication(sys.argv)
os.system('python login_main.py') #执行login_main.py文件,即登录界面
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
就可以实现,登录界面,在输入正确的账号和密码后,就可以调到主界面。
登录界面源代码#login_main.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: diyun
# time:2020.9.7
from PyQt5.QtCore import Qt pyqtSignal QPoint
from PyQt5.QtGui import QFont QEnterEvent QPainter QColor QPen
from PyQt5.QtWidgets import QHBoxLayout QLabel QSpacerItem QSizePolicy
from PyQt5.QtWidgets import QWidget QVBoxLayout QPushButton QTextEdit
from qtpy import QtGui
import sys
import qdarkstyle
from PyQt5.QtCore import QSize
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QComboBox
from PyQt5.QtWidgets import QGridLayout
from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtWidgets import QLabel
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QWidget QVBoxLayout QPushButton QTextEdit
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
#from Header import TitleBar FramelessWindow
from qtpy import QtGui
from PyQt5.QtGui import QFont
StyleSheet = """
/*最小化最大化关闭按钮通用默认背景*/
#buttonMinimum #buttonMaximum #buttonClose {
border: none;
}
#buttonClose #buttonMaximum #buttonMinimum{
color:grey;
}
/*悬停*/
#buttonMinimum:hover #buttonMaximum:hover {
color: white;
}
#buttonClose:hover {
color: white;
}
/*鼠标按下不放*/
#buttonMinimum:pressed #buttonMaximum:pressed {
color:grey;
}
#buttonClose:pressed {
color: white;
}
"""
class TitleBar(QWidget):
# 窗口最小化信号
windowMinimumed = pyqtSignal()
# 窗口最大化信号
windowMaximumed = pyqtSignal()
# 窗口还原信号
windowNormaled = pyqtSignal()
# 窗口关闭信号
windowClosed = pyqtSignal()
# 窗口移动
windowMoved = pyqtSignal(QPoint)
def __init__(self *args **kwargs):
super(TitleBar self).__init__(*args **kwargs)
self.setStyleSheet(StyleSheet)
self.mPos = None
self.iconSize = 20 # 图标的默认大小
# 布局
layout = QHBoxLayout(self spacing=0)
layout.setContentsMargins(0 0 0 0)
# 窗口图标
self.iconLabel = QLabel(self)
# self.iconLabel.setScaledContents(True)
layout.addWidget(self.iconLabel)
# 窗口标题
self.titleLabel = QLabel(self)
self.titleLabel.setStyleSheet("color:grey")
self.titleLabel.setMargin(2)
layout.addWidget(self.titleLabel)
# 中间伸缩条
layout.addSpacerItem(QSpacerItem(
40 20 QSizePolicy.Expanding QSizePolicy.Minimum))
# 利用Webdings字体来显示图标
font = self.font() or QFont()
font.setFamily('Webdings')
# 最小化按钮
self.buttonMinimum = QPushButton(
'0' self clicked=self.windowMinimumed.emit font=font objectName='buttonMinimum')
layout.addWidget(self.buttonMinimum)
# 最大化/还原按钮
self.buttonMaximum = QPushButton(
'1' self clicked=self.showMaximized font=font objectName='buttonMaximum')
layout.addWidget(self.buttonMaximum)
# 关闭按钮
self.buttonClose = QPushButton(
'r' self clicked=self.windowClosed.emit font=font objectName='buttonClose')
layout.addWidget(self.buttonClose)
# 初始高度
self.setHeight()
def showMaximized(self):
if self.buttonMaximum.text() == '1':
# 最大化
self.buttonMaximum.setText('2')
self.windowMaximumed.emit()
else: # 还原
self.buttonMaximum.setText('1')
self.windowNormaled.emit()
def setHeight(self height=38):
"""设置标题栏高度"""
self.setMinimumHeight(height)
self.setMaximumHeight(height)
# 设置右边按钮的大小
self.buttonMinimum.setMinimumSize(height height)
self.buttonMinimum.setMaximumSize(height height)
self.buttonMaximum.setMinimumSize(height height)
self.buttonMaximum.setMaximumSize(height height)
self.buttonClose.setMinimumSize(height height)
self.buttonClose.setMaximumSize(height height)
def setTitle(self title):
"""设置标题"""
self.titleLabel.setText(title)
def setIcon(self icon):
"""设置图标"""
self.iconLabel.setPixmap(icon.pixmap(self.iconSize self.iconSize))
def setIconSize(self size):
"""设置图标大小"""
self.iconSize = size
def enterEvent(self event):
self.setCursor(Qt.ArrowCursor)
super(TitleBar self).enterEvent(event)
def mouseDoubleClickEvent(self event):
super(TitleBar self).mouseDoubleClickEvent(event)
self.showMaximized()
def mousePressEvent(self event):
"""鼠标点击事件"""
if event.button() == Qt.LeftButton:
self.mPos = event.pos()
event.accept()
def mouseReleaseEvent(self event):
'''鼠标弹起事件'''
self.mPos = None
event.accept()
def mouseMoveEvent(self event):
if event.buttons() == Qt.LeftButton and self.mPos:
self.windowMoved.emit(self.mapToGlobal(event.pos() - self.mPos))
event.accept()
# 枚举左上右下以及四个定点
Left Top Right Bottom LeftTop RightTop LeftBottom RightBottom = range(8)
class FramelessWindow(QWidget):
# 四周边距
Margins = 5
def __init__(self *args **kwargs):
super(FramelessWindow self).__init__(*args **kwargs)
palette1 = QtGui.QPalette()
palette1.setBrush(self.backgroundRole() QtGui.QBrush(
QtGui.QPixmap('log0.jpg'))) # 设置登录背景图片
self.setPalette(palette1)
self.setAutoFillBackground(True)
self.setGeometry(300 300 250 150)
self._pressed = False
self.Direction = None
# 无边框
self.setWindowFlags(Qt.FramelessWindowHint) # 隐藏边框
# 鼠标跟踪
self.setMouseTracking(True)
# 布局
layout = QVBoxLayout(self spacing=0)
layout.setContentsMargins(0 0 0 0)
# 标题栏
self.titleBar = TitleBar(self)
layout.addWidget(self.titleBar)
# 信号槽
self.titleBar.windowMinimumed.connect(self.showMinimized)
self.titleBar.windowMaximumed.connect(self.showMaximized)
self.titleBar.windowNormaled.connect(self.showNormal)
self.titleBar.windowClosed.connect(self.close)
self.titleBar.windowMoved.connect(self.move)
self.windowTitleChanged.connect(self.titleBar.setTitle)
self.windowIconChanged.connect(self.titleBar.setIcon)
#def setTitleBarHeight(self height=38):
def setTitleBarHeight(self height=50):
"""设置标题栏高度"""
self.titleBar.setHeight(height)
def setIconSize(self size):
"""设置图标的大小"""
self.titleBar.setIconSize(size)
def setWidget(self widget):
"""设置自己的控件"""
if hasattr(self '_widget'):
return
self._widget = widget
# 设置默认背景颜色 否则由于受到父窗口的影响导致透明
self._widget.setAutoFillBackground(True)
self._widget.installEventFilter(self)
self.layout().addWidget(self._widget)
def move(self pos):
if self.windowState() == Qt.WindowMaximized or self.windowState() == Qt.WindowFullScreen:
# 最大化或者全屏则不允许移动
return
super(FramelessWindow self).move(pos)
def showMaximized(self):
"""最大化 要去除上下左右边界 如果不去除则边框地方会有空隙"""
super(FramelessWindow self).showMaximized()
self.layout().setContentsMargins(0 0 0 0)
def showNormal(self):
"""还原 要保留上下左右边界 否则没有边框无法调整"""
super(FramelessWindow self).showNormal()
self.layout().setContentsMargins(0 0 0 0)
def eventFilter(self obj event):
"""事件过滤器 用于解决鼠标进入其它控件后还原为标准鼠标样式"""
if isinstance(event QEnterEvent):
self.setCursor(Qt.ArrowCursor)
return super(FramelessWindow self).eventFilter(obj event)
def paintEvent(self event):
"""由于是全透明背景窗口 重绘事件中绘制透明度为1的难以发现的边框 用于调整窗口大小"""
super(FramelessWindow self).paintEvent(event)
painter = QPainter(self)
painter.setPen(QPen(QColor(255 255 255 1) 2 * self.Margins))
painter.drawRect(self.rect())
def mousePressEvent(self event):
"""鼠标点击事件"""
super(FramelessWindow self).mousePressEvent(event)
if event.button() == Qt.LeftButton:
self._mpos = event.pos()
self._pressed = True
def mouseReleaseEvent(self event):
'''鼠标弹起事件'''
super(FramelessWindow self).mouseReleaseEvent(event)
self._pressed = False
self.Direction = None
def mouseMoveEvent(self event):
"""鼠标移动事件"""
super(FramelessWindow self).mouseMoveEvent(event)
pos = event.pos()
xPos yPos = pos.x() pos.y()
wm hm = self.width() - self.Margins self.height() - self.Margins
if self.isMaximized() or self.isFullScreen():
self.Direction = None
self.setCursor(Qt.ArrowCursor)
return
if event.buttons() == Qt.LeftButton and self._pressed:
self._resizeWidget(pos)
return
if xPos <= self.Margins and yPos <= self.Margins:
# 左上角
self.Direction = LeftTop
self.setCursor(Qt.SizeFDiagCursor)
elif wm <= xPos <= self.width() and hm <= yPos <= self.height():
# 右下角
self.Direction = RightBottom
self.setCursor(Qt.SizeFDiagCursor)
elif wm <= xPos and yPos <= self.Margins:
# 右上角
self.Direction = RightTop
self.setCursor(Qt.SizeBDiagCursor)
elif xPos <= self.Margins and hm <= yPos:
# 左下角
self.Direction = LeftBottom
self.setCursor(Qt.SizeBDiagCursor)
elif 0 <= xPos <= self.Margins and self.Margins <= yPos <= hm:
# 左边
self.Direction = Left
self.setCursor(Qt.SizeHorCursor)
elif wm <= xPos <= self.width() and self.Margins <= yPos <= hm:
# 右边
self.Direction = Right
self.setCursor(Qt.SizeHorCursor)
elif self.Margins <= xPos <= wm and 0 <= yPos <= self.Margins:
# 上面
self.Direction = Top
self.setCursor(Qt.SizeVerCursor)
elif self.Margins <= xPos <= wm and hm <= yPos <= self.height():
# 下面
self.Direction = Bottom
self.setCursor(Qt.SizeVerCursor)
def _resizeWidget(self pos):
"""调整窗口大小"""
if self.Direction == None:
return
mpos = pos - self._mpos
xPos yPos = mpos.x() mpos.y()
geometry = self.geometry()
x y w h = geometry.x() geometry.y() geometry.width() geometry.height()
if self.Direction == LeftTop: # 左上角
if w - xPos > self.minimumWidth():
x = xPos
w -= xPos
if h - yPos > self.minimumHeight():
y = yPos
h -= yPos
elif self.Direction == RightBottom: # 右下角
if w xPos > self.minimumWidth():
w = xPos
self._mpos = pos
if h yPos > self.minimumHeight():
h = yPos
self._mpos = pos
elif self.Direction == RightTop: # 右上角
if h - yPos > self.minimumHeight():
y = yPos
h -= yPos
if w xPos > self.minimumWidth():
w = xPos
self._mpos.setX(pos.x())
elif self.Direction == LeftBottom: # 左下角
if w - xPos > self.minimumWidth():
x = xPos
w -= xPos
if h yPos > self.minimumHeight():
h = yPos
self._mpos.setY(pos.y())
elif self.Direction == Left: # 左边
if w - xPos > self.minimumWidth():
x = xPos
w -= xPos
else:
return
elif self.Direction == Right: # 右边
if w xPos > self.minimumWidth():
w = xPos
self._mpos = pos
else:
return
elif self.Direction == Top: # 上面
if h - yPos > self.minimumHeight():
y = yPos
h -= yPos
else:
return
elif self.Direction == Bottom: # 下面
if h yPos > self.minimumHeight():
h = yPos
self._mpos = pos
else:
return
self.setGeometry(x y w h)
StyleSheet_2 = """
QComboBox{
height: 20px;
border-radius: 4px;
border: 1px solid rgb(111 156 207);
background: white;
}
QComboBox:enabled{
color: grey;
}
QComboBox:!enabled {
color: rgb(80 80 80);
}
QComboBox:enabled:hover QComboBox:enabled:focus {
color: rgb(51 51 51);
}
QComboBox::drop-down {
background: transparent;
}
QComboBox::drop-down:hover {
background: lightgrey;
}
QComboBox QAbstractItemView {
border: 1px solid rgb(111 156 207);
background: white;
outline: none;
}
QLineEdit {
border-radius: 4px;
height: 20px;
border: 1px solid rgb(111 156 207);
background: white;
}
QLineEdit:enabled {
color: rgb(84 84 84);
}
QLineEdit:enabled:hover QLineEdit:enabled:focus {
color: rgb(51 51 51);
}
QLineEdit:!enabled {
color: rgb(80 80 80);
}
""" #QComobox和QLineEdite的样式
StyleSheet_btn = """
QPushButton{
height:30px;
background-color: transparent;
color: grey;
border: 2px solid #555555;
border-radius: 6px;
}
QPushButton:hover {
background-color: blue;
border-radius: 6px;
}
""" #登录Button的样式
class loginWnd(QWidget):
'''登录窗口'''
def __init__(self *args **kwargs):
super(loginWnd self).__init__()
self._layout = QVBoxLayout(spacing=0)
self._layout.setContentsMargins(0 0 0 0)
self.setAutoFillBackground(True)
self.setWindowOpacity(0.9)#透明度
self.setLayout(self._layout)
self._setup_ui()
def _setup_ui(self):
self.main_layout = QGridLayout()
self.main_layout.setAlignment(Qt.AlignCenter)
name_label = QLabel('账号:')
name_label.setStyleSheet("color:black;")#设置颜色
name_label.setFont(QFont("SimSun" 13 50))#设置字体及大小 第一个参数是字体(微软雅黑),第二个是字体大小,第三个是加粗(50代表正常)
passwd_label = QLabel('密码:')
passwd_label.setStyleSheet("color:black;")
passwd_label.setFont(QFont("SimSun" 13 50))
# self.name_box = QComboBox()
# self.name_box.setEditable(True)
self.name_box = QLineEdit()
#self.name_box.setEchoMode(QLineEdit.Password)
#self.name_box.setEditable(True)
self.passwd_box = QLineEdit()
self.passwd_box.setEchoMode(QLineEdit.Password)
self.name_box.setStyleSheet(StyleSheet_2)
self.passwd_box.setStyleSheet(StyleSheet_2)
label = QLabel()
login_btn = QPushButton("登录")
login_btn.setStyleSheet(StyleSheet_btn)
login_btn.setStyleSheet("color:red;")
login_btn.setFont(QFont("Microsoft YaHei" 15 50))
self.main_layout.addWidget(name_label 0 0 1 1) #坐标(0,0)的组件占用一行一列
self.main_layout.addWidget(passwd_label 1 0 1 1)
self.main_layout.addWidget(self.name_box 0 1 1 2)
self.main_layout.addWidget(self.passwd_box 1 1 1 2)
self.main_layout.addWidget(label 3 0 1 3)
self.main_layout.addWidget(login_btn 4 0 1 3)
self._layout.addLayout(self.main_layout)
###### 绑定按钮事件
login_btn.clicked.connect(self.on_pushButton_enter_clicked)
def on_pushButton_enter_clicked(self text):
print("进入账号判断函数")
if self.name_box.text() == "diyun":
print("账号正确")
if self.passwd_box.text() == "12345":
print("密码正确")
print("输入正确 跳转至主界面")
#self.close() # 关闭登陆界面
mainWnd.close()#关闭登陆界面,在这之后就可以进入你编写的其他界面了。
else:
print("密码不正确")
else:
print("用户名不正确")
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWnd = FramelessWindow()
mainWnd.setWindowTitle('登录')
mainWnd.setWindowIcon(QIcon('Qt.ico'))
mainWnd.setFixedSize(QSize(650 500)) #因为这里固定了大小,所以窗口的大小没有办法任意调整,想要使resizeWidget函数生效的话要把这里去掉,自己调节布局和窗口大小
mainWnd.setWidget(loginWnd(mainWnd)) # 把自己的窗口添加进来
mainWnd.show()
app.exec()