效果图
代码
本例只要注册,暂时没有登录。
# -*- coding: utf-8 -*-
'''**************************************************************************
版本:1.0
内容:注册界面设计,分文件
时间:2021.9.24
作者:狄云
***************************************************************************'''
import pymysql
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 PyQt5 import QtGui
import sys
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 PyQt5 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('./input/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 regist(QWidget):
'''登录窗口'''
def __init__(self, *args, **kwargs):
super(regist, 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 = QLineEdit()
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)
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._layout.addLayout(self.main_layout)
# 绑定按钮事件
login_btn.clicked.connect(self.insert_Mysql_userinfo)
# 获取连接
def get_Mysql_conn(self):
try:
config = {
"host": "localhost",
"user": "root",
"password": "root",
"database": "test_0505"
}
self.conn = pymysql.connect(**config)
except pymysql.Error as e:
print('Error: %s' % e)
# 关闭连接
def close_Mysql_conn(self):
try:
if self.conn:
self.conn.close()
except pymysql.Error as e:
print('Error: %s' % e)
# 获取用户信息(登录用)
def get_Mysql_userinfo(self):
self.get_Mysql_conn()
sql = ' SELECT * FROM userinfo' #这里我的登录用户头叫userinfo ,每个人的数据库不同,在建立时初始化。
# 使用cursor()方法获取操作游标
cursor = self.conn.cursor()
# 使用execute()方法执行SQL语句
cursor.execute(sql)
# 使用fetchall()方法获取全部数据
result = cursor.fetchall()
# 将数据用字典形式存储于result
result = [dict(zip([k[0] for k in cursor.description], row)) for row in result]
# 关闭连接
cursor.close()
self.close_Mysql_conn()
return result
# 注册
def insert_Mysql_userinfo(self, text):
print("进入用户注册提交函数22")
self.name = str(self.name_box.text())
self.pwd = str(self.passwd_box.text())
self.get_Mysql_conn()#连接数据库
sql = 'SELECT * FROM userinfo'
cursor = self.conn.cursor()
cursor.execute(sql)
result = cursor.fetchall()
print("result=", result)
result = [dict(zip([k[0] for k in cursor.description], row)) for row in result]
ulist = []
for item in result:
ulist.append(item['name'])
print("ulist=", ulist)
try:
sql = "insert into userinfo(name, pwd) values('{}', '{}');".format(self.name,self.pwd)
cursor.execute(sql)
if self.name == '' or self.pwd == '':
self.conn.rollback()
QMessageBox.warning(self, "警告", "账号或者密码有空,注册失败", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
elif self.name in ulist:
#messagebox.showerror('警告', message='用户名已存在')
#msg_box = QMessageBox(QMessageBox.Warning, '警告', '用户名已存在')
QMessageBox.warning(self, "警告", "用户名已存在", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
else:
# 提交事务
self.conn.commit()
#messagebox.showinfo(title='恭喜', message='注册成功')
#msg_box = QMessageBox(QMessageBox.information, '恭喜', '注册成功')
QMessageBox.information(self, "恭喜", "注册成功", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
mainWnd2.close() # 关闭注册界面,在这之后就可以进入你编写的其他界面了。
cursor.close()
self.close_conn()
except:
# 限制提交
self.conn.rollback()
#登录 本例没用
def on_pushButton_Login_clicked(self, text):
print("进入账号判断函数")
self.get_Mysql_conn() # 连接数据库
sql = 'SELECT * FROM userinfo'
cursor = self.conn.cursor()
cursor.execute(sql)
data = cursor.fetchall()
# 打印获取到的数据
for i in range(len(data)):
#print(data[i][1])
#print(data[i][2])
if self.name_box.text() == data[i][1]:
print("账号正确")
if self.passwd_box.text() == data[i][2]:
print("密码正确")
#mainWnd.close() # 关闭登陆界面,在这之后就可以进入你编写的其他界面了。
cursor.close()
self.close_conn()
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWnd2 = FramelessWindow()
mainWnd2.setWindowTitle('注册')
mainWnd2.setWindowIcon(QIcon('Qt.ico'))
mainWnd2.setFixedSize(QSize(650, 500)) # 因为这里固定了大小,所以窗口的大小没有办法任意调整,想要使resizeWidget函数生效的话要把这里去掉,自己调节布局和窗口大小
mainWnd2.setWidget(regist(mainWnd2)) # 把自己的窗口添加进来
mainWnd2.show()
app.exec()