PyQt:个性化登录界面模仿QQ登录

写在前面

  写了一个登录界面的demo,类似QQ的,写的自己喜欢的样式,贴一下代码,先上效果,如下

陈述

  PyQt5+Python3.5.2

  login.py是里登录的主界面loginWnd类,Header.py里是标题栏和整个窗口的类,我在login.py里面创建了application对象。(其实也没有必要分成两个文件来写,直接按照我这一篇的处理就ok的     https://www.cnblogs.com/jyroy/p/9461317.html,本人话多

  主要是效果实现为主,没有写登录的槽函数啥的,代码中写了解释

效果

 

代码

  1 #login.py
  2 
  3 #!/usr/bin/env python
  4 # -*- coding:utf-8 -*-
  5 # Author: jyroy
  6 import sys
  7 
  8 from PyQt5.QtCore import QSize
  9 from PyQt5.QtWidgets import QApplication
 10 from PyQt5.QtCore import Qt
 11 from PyQt5.QtWidgets import QComboBox
 12 from PyQt5.QtWidgets import QGridLayout
 13 from PyQt5.QtWidgets import QLineEdit
 14 from PyQt5.QtWidgets import QLabel
 15 from PyQt5.QtGui import QIcon
 16 from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton, QTextEdit
 17 from Header import TitleBar,FramelessWindow
 18 from qtpy import QtGui
 19 
 20 StyleSheet = """
 21 /*最小化最大化关闭按钮通用默认背景*/
 22 #buttonMinimum,#buttonMaximum,#buttonClose {
 23     border: none;
 24 }
 25 /*悬停*/
 26 #buttonMinimum:hover,#buttonMaximum:hover {
 27 
 28     color: white;
 29 }
 30 #buttonClose:hover {
 31     color: white;
 32 }
 33 /*鼠标按下不放*/
 34 #buttonMinimum:pressed,#buttonMaximum:pressed {
 35 
 36 }
 37 #buttonClose:pressed {
 38     color: white;
 39 
 40 }
 41 """   #标题栏Button的样式
 42 
 43 StyleSheet_2 = """
 44 QComboBox{
 45         height: 20px;
 46         border-radius: 4px;
 47         border: 1px solid rgb(111, 156, 207);
 48         background: white;
 49 }
 50 QComboBox:enabled{
 51         color: grey;
 52 }
 53 QComboBox:!enabled {
 54         color: rgb(80, 80, 80);
 55 }
 56 QComboBox:enabled:hover, QComboBox:enabled:focus {
 57         color: rgb(51, 51, 51);
 58 }
 59 QComboBox::drop-down {
 60         background: transparent;
 61 }
 62 QComboBox::drop-down:hover {
 63         background: lightgrey;
 64 }
 65 
 66 QComboBox QAbstractItemView {
 67         border: 1px solid rgb(111, 156, 207);
 68         background: white;
 69         outline: none;
 70 }
 71 
 72  QLineEdit {
 73         border-radius: 4px;
 74         height: 20px;
 75         border: 1px solid rgb(111, 156, 207);
 76         background: white;
 77 }
 78 QLineEdit:enabled {
 79         color: rgb(84, 84, 84);
 80 }
 81 QLineEdit:enabled:hover, QLineEdit:enabled:focus {
 82         color: rgb(51, 51, 51);
 83 }
 84 QLineEdit:!enabled {
 85         color: rgb(80, 80, 80);
 86 }
 87 
 88 
 89 """   #QComobox和QLineEdite的样式
 90 
 91 StyleSheet_btn = """
 92 QPushButton{
 93     height:30px;
 94     background-color: transparent;
 95     color: grey;
 96     border: 2px solid #555555;
 97     border-radius: 6px;
 98 
 99 }
100 QPushButton:hover {
101     background-color: white;
102     border-radius: 6px;
103 
104 }
105 """  #登录Button的样式
106 
107 class loginWnd(QWidget):
108     '''登录窗口'''
109     def __init__(self, *args, **kwargs):
110         super(loginWnd, self).__init__()
111         self._layout = QVBoxLayout(spacing=0)
112         self._layout.setContentsMargins(0, 0, 0, 0)
113         self.setAutoFillBackground(True)
114         self.setWindowOpacity(0.1)
115 
116         self.setLayout(self._layout)
117 
118         self._setup_ui()
119 
120     def _setup_ui(self):
121 
122         self.main_layout = QGridLayout()
123 
124         self.main_layout.setAlignment(Qt.AlignCenter)
125 
126         name_label = QLabel('用户名')
127         name_label.setStyleSheet("color:grey;")
128         passwd_label = QLabel('密码')
129         passwd_label.setStyleSheet("color:grey;")
130 
131         name_box = QComboBox()
132         name_box.setEditable(True)
133         passwd_box = QLineEdit()
134         passwd_box.setEchoMode(QLineEdit.Password)
135         name_box.setStyleSheet(StyleSheet_2)
136         passwd_box.setStyleSheet(StyleSheet_2)
137 
138         label = QLabel()
139 
140         login_btn = QPushButton("登录")
141         login_btn.setStyleSheet(StyleSheet_btn)
142 
143         self.main_layout.addWidget(name_label,0,0,1,1)
144         self.main_layout.addWidget(passwd_label,1,0,1,1)
145         self.main_layout.addWidget(name_box,0,1,1,2)
146         self.main_layout.addWidget(passwd_box,1,1,1, 2)
147         self.main_layout.addWidget(label,3,0,1,3)
148         self.main_layout.addWidget(login_btn,4,0,1,3)
149 
150         self._layout.addLayout(self.main_layout)
151 
152 def main():
153     ''':return:'''
154 
155     app = QApplication(sys.argv)
156 
157     mainWnd = FramelessWindow()
158     mainWnd.setWindowTitle('欢迎窗口login')
159     mainWnd.setWindowIcon(QIcon('Qt.ico'))
160     mainWnd.setFixedSize(QSize(500,400))  #因为这里固定了大小,所以窗口的大小没有办法任意调整,想要使resizeWidget函数生效的话要把这里去掉,自己调节布局和窗口大小
161     mainWnd.setWidget(loginWnd(mainWnd))  # 把自己的窗口添加进来
162     mainWnd.show()
163 
164     app.exec()
165 
166 if __name__ == '__main__':
167     main()

 

 

  1 #Header.py
  2 
  3 #!/usr/bin/env python
  4 # -*- coding:utf-8 -*-
  5 # Author: jyroy
  6 
  7 from PyQt5.QtCore import Qt, pyqtSignal, QPoint
  8 from PyQt5.QtGui import QFont, QEnterEvent, QPainter, QColor, QPen
  9 from PyQt5.QtWidgets import QHBoxLayout, QLabel,QSpacerItem, QSizePolicy
 10 from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton, QTextEdit
 11 from qtpy import QtGui
 12 
 13 StyleSheet = """
 14 /*最小化最大化关闭按钮通用默认背景*/
 15 #buttonMinimum,#buttonMaximum,#buttonClose {
 16     border: none;
 17 }
 18 #buttonClose,#buttonMaximum,#buttonMinimum{
 19     color:grey;
 20 }
 21 /*悬停*/
 22 #buttonMinimum:hover,#buttonMaximum:hover {
 23     color: white;
 24 }
 25 #buttonClose:hover {
 26     color: white;
 27 }
 28 /*鼠标按下不放*/
 29 #buttonMinimum:pressed,#buttonMaximum:pressed {
 30     color:grey;
 31 }
 32 #buttonClose:pressed {
 33     color: white;
 34 
 35 }
 36 """
 37 class TitleBar(QWidget):
 38 
 39     # 窗口最小化信号
 40     windowMinimumed = pyqtSignal()
 41     # 窗口最大化信号
 42     windowMaximumed = pyqtSignal()
 43     # 窗口还原信号
 44     windowNormaled = pyqtSignal()
 45     # 窗口关闭信号
 46     windowClosed = pyqtSignal()
 47     # 窗口移动
 48     windowMoved = pyqtSignal(QPoint)
 49 
 50     def __init__(self, *args, **kwargs):
 51         super(TitleBar, self).__init__(*args, **kwargs)
 52         self.setStyleSheet(StyleSheet)
 53         self.mPos = None
 54         self.iconSize = 20  # 图标的默认大小
 55         # 布局
 56         layout = QHBoxLayout(self, spacing=0)
 57         layout.setContentsMargins(0, 0, 0, 0)
 58         # 窗口图标
 59         self.iconLabel = QLabel(self)
 60 #         self.iconLabel.setScaledContents(True)
 61         layout.addWidget(self.iconLabel)
 62         # 窗口标题
 63         self.titleLabel = QLabel(self)
 64         self.titleLabel.setStyleSheet("color:grey")
 65         self.titleLabel.setMargin(2)
 66         layout.addWidget(self.titleLabel)
 67         # 中间伸缩条
 68         layout.addSpacerItem(QSpacerItem(
 69             40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum))
 70         # 利用Webdings字体来显示图标
 71         font = self.font() or QFont()
 72         font.setFamily('Webdings')
 73         # 最小化按钮
 74         self.buttonMinimum = QPushButton(
 75             '0', self, clicked=self.windowMinimumed.emit, font=font, objectName='buttonMinimum')
 76         layout.addWidget(self.buttonMinimum)
 77         # 最大化/还原按钮
 78         self.buttonMaximum = QPushButton(
 79             '1', self, clicked=self.showMaximized, font=font, objectName='buttonMaximum')
 80         layout.addWidget(self.buttonMaximum)
 81         # 关闭按钮
 82         self.buttonClose = QPushButton(
 83             'r', self, clicked=self.windowClosed.emit, font=font, objectName='buttonClose')
 84         layout.addWidget(self.buttonClose)
 85         # 初始高度
 86         self.setHeight()
 87 
 88     def showMaximized(self):
 89         if self.buttonMaximum.text() == '1':
 90             # 最大化
 91             self.buttonMaximum.setText('2')
 92             self.windowMaximumed.emit()
 93         else:  # 还原
 94             self.buttonMaximum.setText('1')
 95             self.windowNormaled.emit()
 96 
 97     def setHeight(self, height=38):
 98         """设置标题栏高度"""
 99         self.setMinimumHeight(height)
100         self.setMaximumHeight(height)
101         # 设置右边按钮的大小
102         self.buttonMinimum.setMinimumSize(height, height)
103         self.buttonMinimum.setMaximumSize(height, height)
104         self.buttonMaximum.setMinimumSize(height, height)
105         self.buttonMaximum.setMaximumSize(height, height)
106         self.buttonClose.setMinimumSize(height, height)
107         self.buttonClose.setMaximumSize(height, height)
108 
109     def setTitle(self, title):
110         """设置标题"""
111         self.titleLabel.setText(title)
112 
113     def setIcon(self, icon):
114         """设置图标"""
115         self.iconLabel.setPixmap(icon.pixmap(self.iconSize, self.iconSize))
116 
117     def setIconSize(self, size):
118         """设置图标大小"""
119         self.iconSize = size
120 
121     def enterEvent(self, event):
122         self.setCursor(Qt.ArrowCursor)
123         super(TitleBar, self).enterEvent(event)
124 
125     def mouseDoubleClickEvent(self, event):
126         super(TitleBar, self).mouseDoubleClickEvent(event)
127         self.showMaximized()
128 
129     def mousePressEvent(self, event):
130         """鼠标点击事件"""
131         if event.button() == Qt.LeftButton:
132             self.mPos = event.pos()
133         event.accept()
134 
135     def mouseReleaseEvent(self, event):
136         '''鼠标弹起事件'''
137         self.mPos = None
138         event.accept()
139 
140     def mouseMoveEvent(self, event):
141         if event.buttons() == Qt.LeftButton and self.mPos:
142             self.windowMoved.emit(self.mapToGlobal(event.pos() - self.mPos))
143         event.accept()
144 
145 # 枚举左上右下以及四个定点
146 Left, Top, Right, Bottom, LeftTop, RightTop, LeftBottom, RightBottom = range(8)
147 
148 class FramelessWindow(QWidget):
149 
150     # 四周边距
151     Margins = 5
152 
153     def __init__(self, *args, **kwargs):
154         super(FramelessWindow, self).__init__(*args, **kwargs)
155         palette1 = QtGui.QPalette()
156         palette1.setBrush(self.backgroundRole(), QtGui.QBrush(
157             QtGui.QPixmap('D:\python\code\qilucontest\qt\WholeDemo/resource/sky.jpg')))  # 设置背景图片
158         self.setPalette(palette1)
159         self.setAutoFillBackground(True)
160         self.setGeometry(300, 300, 250, 150)
161         self._pressed = False
162         self.Direction = None
163         # 无边框
164         self.setWindowFlags(Qt.FramelessWindowHint)  # 隐藏边框
165         # 鼠标跟踪
166         self.setMouseTracking(True)
167         # 布局
168         layout = QVBoxLayout(self, spacing=0)
169         layout.setContentsMargins(0,0,0,0)
170         # 标题栏
171         self.titleBar = TitleBar(self)
172         layout.addWidget(self.titleBar)
173         # 信号槽
174         self.titleBar.windowMinimumed.connect(self.showMinimized)
175         self.titleBar.windowMaximumed.connect(self.showMaximized)
176         self.titleBar.windowNormaled.connect(self.showNormal)
177         self.titleBar.windowClosed.connect(self.close)
178         self.titleBar.windowMoved.connect(self.move)
179         self.windowTitleChanged.connect(self.titleBar.setTitle)
180         self.windowIconChanged.connect(self.titleBar.setIcon)
181 
182     def setTitleBarHeight(self, height=38):
183         """设置标题栏高度"""
184         self.titleBar.setHeight(height) 
185 
186     def setIconSize(self, size):
187         """设置图标的大小"""
188         self.titleBar.setIconSize(size)
189 
190     def setWidget(self, widget):
191         """设置自己的控件"""
192         if hasattr(self, '_widget'):
193             return
194         self._widget = widget
195         # 设置默认背景颜色,否则由于受到父窗口的影响导致透明
196         self._widget.setAutoFillBackground(True)
197         self._widget.installEventFilter(self)
198         self.layout().addWidget(self._widget)
199 
200     def move(self, pos):
201         if self.windowState() == Qt.WindowMaximized or self.windowState() == Qt.WindowFullScreen:
202             # 最大化或者全屏则不允许移动
203             return
204         super(FramelessWindow, self).move(pos)
205 
206     def showMaximized(self):
207         """最大化,要去除上下左右边界,如果不去除则边框地方会有空隙"""
208         super(FramelessWindow, self).showMaximized()
209         self.layout().setContentsMargins(0, 0, 0, 0)
210 
211     def showNormal(self):
212         """还原,要保留上下左右边界,否则没有边框无法调整"""
213         super(FramelessWindow, self).showNormal()
214         self.layout().setContentsMargins(0, 0, 0, 0)
215 
216     def eventFilter(self, obj, event):
217         """事件过滤器,用于解决鼠标进入其它控件后还原为标准鼠标样式"""
218         if isinstance(event, QEnterEvent):
219             self.setCursor(Qt.ArrowCursor)
220         return super(FramelessWindow, self).eventFilter(obj, event)
221 
222     def paintEvent(self, event):
223         """由于是全透明背景窗口,重绘事件中绘制透明度为1的难以发现的边框,用于调整窗口大小"""
224         super(FramelessWindow, self).paintEvent(event)
225         painter = QPainter(self)
226         painter.setPen(QPen(QColor(255, 255, 255, 1), 2 * self.Margins))
227         painter.drawRect(self.rect())
228 
229     def mousePressEvent(self, event):
230         """鼠标点击事件"""
231         super(FramelessWindow, self).mousePressEvent(event)
232         if event.button() == Qt.LeftButton:
233             self._mpos = event.pos()
234             self._pressed = True
235 
236     def mouseReleaseEvent(self, event):
237         '''鼠标弹起事件'''
238         super(FramelessWindow, self).mouseReleaseEvent(event)
239         self._pressed = False
240         self.Direction = None
241 
242     def mouseMoveEvent(self, event):
243         """鼠标移动事件"""
244         super(FramelessWindow, self).mouseMoveEvent(event)
245         pos = event.pos()
246         xPos, yPos = pos.x(), pos.y()
247         wm, hm = self.width() - self.Margins, self.height() - self.Margins
248         if self.isMaximized() or self.isFullScreen():
249             self.Direction = None
250             self.setCursor(Qt.ArrowCursor)
251             return
252         if event.buttons() == Qt.LeftButton and self._pressed:
253             self._resizeWidget(pos)
254             return
255         if xPos <= self.Margins and yPos <= self.Margins:
256             # 左上角
257             self.Direction = LeftTop
258             self.setCursor(Qt.SizeFDiagCursor)
259         elif wm <= xPos <= self.width() and hm <= yPos <= self.height():
260             # 右下角
261             self.Direction = RightBottom
262             self.setCursor(Qt.SizeFDiagCursor)
263         elif wm <= xPos and yPos <= self.Margins:
264             # 右上角
265             self.Direction = RightTop
266             self.setCursor(Qt.SizeBDiagCursor)
267         elif xPos <= self.Margins and hm <= yPos:
268             # 左下角
269             self.Direction = LeftBottom
270             self.setCursor(Qt.SizeBDiagCursor)
271         elif 0 <= xPos <= self.Margins and self.Margins <= yPos <= hm:
272             # 左边
273             self.Direction = Left
274             self.setCursor(Qt.SizeHorCursor)
275         elif wm <= xPos <= self.width() and self.Margins <= yPos <= hm:
276             # 右边
277             self.Direction = Right
278             self.setCursor(Qt.SizeHorCursor)
279         elif self.Margins <= xPos <= wm and 0 <= yPos <= self.Margins:
280             # 上面
281             self.Direction = Top
282             self.setCursor(Qt.SizeVerCursor)
283         elif self.Margins <= xPos <= wm and hm <= yPos <= self.height():
284             # 下面
285             self.Direction = Bottom
286             self.setCursor(Qt.SizeVerCursor)
287 
288     def _resizeWidget(self, pos):
289         """调整窗口大小"""
290         if self.Direction == None:
291             return
292         mpos = pos - self._mpos
293         xPos, yPos = mpos.x(), mpos.y()
294         geometry = self.geometry()
295         x, y, w, h = geometry.x(), geometry.y(), geometry.width(), geometry.height()
296         if self.Direction == LeftTop:  # 左上角
297             if w - xPos > self.minimumWidth():
298                 x += xPos
299                 w -= xPos
300             if h - yPos > self.minimumHeight():
301                 y += yPos
302                 h -= yPos
303         elif self.Direction == RightBottom:  # 右下角
304             if w + xPos > self.minimumWidth():
305                 w += xPos
306                 self._mpos = pos
307             if h + yPos > self.minimumHeight():
308                 h += yPos
309                 self._mpos = pos
310         elif self.Direction == RightTop:  # 右上角
311             if h - yPos > self.minimumHeight():
312                 y += yPos
313                 h -= yPos
314             if w + xPos > self.minimumWidth():
315                 w += xPos
316                 self._mpos.setX(pos.x())
317         elif self.Direction == LeftBottom:  # 左下角
318             if w - xPos > self.minimumWidth():
319                 x += xPos
320                 w -= xPos
321             if h + yPos > self.minimumHeight():
322                 h += yPos
323                 self._mpos.setY(pos.y())
324         elif self.Direction == Left:  # 左边
325             if w - xPos > self.minimumWidth():
326                 x += xPos
327                 w -= xPos
328             else:
329                 return
330         elif self.Direction == Right:  # 右边
331             if w + xPos > self.minimumWidth():
332                 w += xPos
333                 self._mpos = pos
334             else:
335                 return
336         elif self.Direction == Top:  # 上面
337             if h - yPos > self.minimumHeight():
338                 y += yPos
339                 h -= yPos
340             else:
341                 return
342         elif self.Direction == Bottom:  # 下面
343             if h + yPos > self.minimumHeight():
344                 h += yPos
345                 self._mpos = pos
346             else:
347                 return
348         self.setGeometry(x, y, w, h)

 

转载于:https://www.cnblogs.com/jyroy/p/9465034.html

你可能感兴趣的:(PyQt:个性化登录界面模仿QQ登录)