无边框自定义标题栏窗口

This commit is contained in:
Irony 2018-04-30 15:41:14 +08:00
parent a2891d3d79
commit d692d4b8a5
6 changed files with 159 additions and 2 deletions

View file

@ -44,6 +44,7 @@ encoding//\u5B57\u4F53\u6D4B\u8BD5/FontAwesome.py=utf-8
encoding//\u5B57\u4F53\u6D4B\u8BD5/TestFontAwesome.py=utf-8 encoding//\u5B57\u4F53\u6D4B\u8BD5/TestFontAwesome.py=utf-8
encoding//\u5B57\u4F53\u6D4B\u8BD5/TestFontRoboto.py=utf-8 encoding//\u5B57\u4F53\u6D4B\u8BD5/TestFontRoboto.py=utf-8
encoding//\u65E0\u8FB9\u6846\u81EA\u5B9A\u4E49\u6807\u9898\u680F\u7A97\u53E3/FramelessWindow.py=utf-8 encoding//\u65E0\u8FB9\u6846\u81EA\u5B9A\u4E49\u6807\u9898\u680F\u7A97\u53E3/FramelessWindow.py=utf-8
encoding//\u65E0\u8FB9\u6846\u81EA\u5B9A\u4E49\u6807\u9898\u680F\u7A97\u53E3/Test.py=utf-8
encoding//\u68A6\u5E7B\u6811/DreamTree.py=utf-8 encoding//\u68A6\u5E7B\u6811/DreamTree.py=utf-8
encoding//\u6C14\u6CE1\u63D0\u793A/BubbleTips.py=utf-8 encoding//\u6C14\u6CE1\u63D0\u793A/BubbleTips.py=utf-8
encoding//\u6D4F\u89C8\u5668\u83B7\u53D6Cookie/WebEngineView.py=utf-8 encoding//\u6D4F\u89C8\u5668\u83B7\u53D6Cookie/WebEngineView.py=utf-8

View file

@ -37,6 +37,7 @@ class TitleBar(QWidget):
# 支持qss设置背景 # 支持qss设置背景
self.setAttribute(Qt.WA_StyledBackground, True) self.setAttribute(Qt.WA_StyledBackground, True)
self.mPos = None self.mPos = None
self.iconSize = 20 # 图标的默认大小
# 设置默认背景颜色,否则由于受到父窗口的影响导致透明 # 设置默认背景颜色,否则由于受到父窗口的影响导致透明
self.setAutoFillBackground(True) self.setAutoFillBackground(True)
palette = self.palette() palette = self.palette()
@ -47,10 +48,11 @@ class TitleBar(QWidget):
layout.setContentsMargins(0, 0, 0, 0) layout.setContentsMargins(0, 0, 0, 0)
# 窗口图标 # 窗口图标
self.iconLabel = QLabel(self) self.iconLabel = QLabel(self)
self.iconLabel.setScaledContents(True) # self.iconLabel.setScaledContents(True)
layout.addWidget(self.iconLabel) layout.addWidget(self.iconLabel)
# 窗口标题 # 窗口标题
self.titleLabel = QLabel(self) self.titleLabel = QLabel(self)
self.titleLabel.setMargin(2)
layout.addWidget(self.titleLabel) layout.addWidget(self.titleLabel)
# 中间伸缩条 # 中间伸缩条
layout.addSpacerItem(QSpacerItem( layout.addSpacerItem(QSpacerItem(
@ -100,7 +102,11 @@ class TitleBar(QWidget):
def setIcon(self, icon): def setIcon(self, icon):
"""设置图标""" """设置图标"""
self.iconLabel.setPixmap(icon.pixmap(16, 16)) self.iconLabel.setPixmap(icon.pixmap(self.iconSize, self.iconSize))
def setIconSize(self, size):
"""设置图标大小"""
self.iconSize = size
def enterEvent(self, event): def enterEvent(self, event):
self.setCursor(Qt.ArrowCursor) self.setCursor(Qt.ArrowCursor)
@ -167,6 +173,10 @@ class FramelessWindow(QWidget):
"""设置标题栏高度""" """设置标题栏高度"""
self.titleBar.setHeight(height) self.titleBar.setHeight(height)
def setIconSize(self, size):
"""设置图标的大小"""
self.titleBar.setIconSize(size)
def setWidget(self, widget): def setWidget(self, widget):
"""设置自己的控件""" """设置自己的控件"""
if hasattr(self, '_widget'): if hasattr(self, '_widget'):

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View file

@ -0,0 +1,72 @@
# 无边框自定义标题栏窗口
### [Python3.4.4 or Python3.5][PyQt5]
原理说明:
- 使用一个QWidgetFramelessWindow作为父窗口, 一个TitleBar作为标题栏, 一个QWidget作为底部容器
- 父窗口FramelessWindow设置为背景透明但是需要绘制一定宽度的透明度很高的矩形边框用来接受鼠标事件变形鼠标样式进行调整窗口大小
- TitleBar的最小化最大化关闭等按钮事件关联到父窗口里
- TitleBar中的鼠标按下移动事件得到坐标也传递到父窗口调用move方法进行窗口移动
使用方法:
```
class MainWindow(QWidget):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
layout = QVBoxLayout(self, spacing=0)
layout.setContentsMargins(0, 0, 0, 0)
layout.addWidget(QPushButton('按钮', self))
layout.addWidget(QTextEdit(self))
# 样式
StyleSheet = """
/*标题栏*/
TitleBar {
background-color: rgb(54, 157, 180);
}
/*最小化最大化关闭按钮通用默认背景*/
#buttonMinimum,#buttonMaximum,#buttonClose {
border: none;
background-color: rgb(54, 157, 180);
}
/*悬停*/
#buttonMinimum:hover,#buttonMaximum:hover {
background-color: rgb(48, 141, 162);
}
#buttonClose:hover {
color: white;
background-color: rgb(232, 17, 35);
}
/*鼠标按下不放*/
#buttonMinimum:pressed,#buttonMaximum:pressed {
background-color: rgb(44, 125, 144);
}
#buttonClose:pressed {
color: white;
background-color: rgb(161, 73, 92);
}
"""
if __name__ == '__main__':
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
app.setStyleSheet(StyleSheet)
w = FramelessWindow()
w.setWindowTitle('测试标题栏')
w.setWindowIcon(QIcon('Qt.ico'))
w.setWidget(MainWindow(w)) # 把自己的窗口添加进来
w.show()
sys.exit(app.exec_())
```
# 截图
![截图](ScreenShot/1.gif)

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

View file

@ -0,0 +1,74 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton, QTextEdit
from FramelessWindow import FramelessWindow # @UnresolvedImport
# Created on 2018年4月30日
# author: Irony
# site: https://github.com/892768447
# email: 892768447@qq.com
# file: Test
# description:
__Author__ = """By: Irony
QQ: 892768447
Email: 892768447@qq.com"""
__Copyright__ = 'Copyright (c) 2018 Irony'
__Version__ = 1.0
class MainWindow(QWidget):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
layout = QVBoxLayout(self, spacing=0)
layout.setContentsMargins(0, 0, 0, 0)
layout.addWidget(QPushButton('按钮', self))
layout.addWidget(QTextEdit(self))
# 样式
StyleSheet = """
/*标题栏*/
TitleBar {
background-color: rgb(54, 157, 180);
}
/*最小化最大化关闭按钮通用默认背景*/
#buttonMinimum,#buttonMaximum,#buttonClose {
border: none;
background-color: rgb(54, 157, 180);
}
/*悬停*/
#buttonMinimum:hover,#buttonMaximum:hover {
background-color: rgb(48, 141, 162);
}
#buttonClose:hover {
color: white;
background-color: rgb(232, 17, 35);
}
/*鼠标按下不放*/
#buttonMinimum:pressed,#buttonMaximum:pressed {
background-color: rgb(44, 125, 144);
}
#buttonClose:pressed {
color: white;
background-color: rgb(161, 73, 92);
}
"""
if __name__ == '__main__':
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
app.setStyleSheet(StyleSheet)
w = FramelessWindow()
w.setWindowTitle('测试标题栏')
w.setWindowIcon(QIcon('Qt.ico'))
w.setWidget(MainWindow(w)) # 把自己的窗口添加进来
w.show()
sys.exit(app.exec_())