使用Python3.6.3
PyQt5.13.0

构建了一个无边框窗口可以使用。
支持鼠标边缘拖拽大小。
支持双击标题最大化和还原。
支持按住标题拖拽位置。
上图

包含了标题栏。中心窗口,状态栏。

下载源码资源py文件直接使用传送门

1 使用方式:

from frame_less import FrameLessWindow
fw = FrameLessWindow()
fw.show()

2 功能和API介绍:
最大化。最小化。关闭。

设置标题 fw.setWindowTitle(''要设置的标题)

设置图标 fw.setWindowIcon(QIcon('图标的路径'))

设置中心窗口 fw.set_center_widget(QWidgetObj)

移除状态栏 fw.remove_status_bar()

详细代码:
修改标题背景的颜色和最大小化按钮的颜色样式在TitleBar类QSS

# _*_ coding:utf-8 _*_
# ---------------------------
# Python_Version 3.6.3
# PyQt_Version  5.13.0
# Author: zizle
# Created: 2020-05-16
# ---------------------------
import os
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QPushButton, QLabel, QStatusBar, QStackedWidget
from PyQt5.QtGui import QPixmap, QFont, QEnterEvent, QPainter, QPen, QColor, QIcon
from PyQt5.QtCore import QMargins, Qtfrom frames.price_open_interest import PriceOpenInterest
from settings import BASE_DIRclass TitleBar(QWidget):"""主窗口无边框后使用的标题栏"""def __init__(self, *args, **kwargs):super(TitleBar, self).__init__(*args, **kwargs)self.setAttribute(Qt.WA_StyledBackground, True)  # 支持使用QSS设置背景self._mouse_pos = Nonelayout = QHBoxLayout(self)layout.setContentsMargins(QMargins(3, 3, 3, 3))layout.setSpacing(2)self.title_label = QLabel(self)self.title_label.setScaledContents(True)self.title_label.setFixedSize(20, 20)layout.addWidget(self.title_label, alignment=Qt.AlignLeft)  # 加入窗口图标self.title_text = QLabel(self)self.title_text.setFixedHeight(20)layout.addWidget(self.title_text, alignment=Qt.AlignLeft)  # 加入窗口文字layout.addStretch()self.minimum_button = QPushButton('0', self)self.maximum_button = QPushButton('1', self)self.close_button = QPushButton('r', self)layout.addWidget(self.minimum_button, alignment=Qt.AlignRight)layout.addWidget(self.maximum_button, alignment=Qt.AlignRight)layout.addWidget(self.close_button, alignment=Qt.AlignRight)font = QFont('webdings')  # 使用webding字体设置按钮的图标self.minimum_button.setFont(font)self.maximum_button.setFont(font)self.close_button.setFont(font)self.minimum_button.setFixedSize(20, 20)self.maximum_button.setFixedSize(20, 20)self.close_button.setFixedSize(20, 20)self.minimum_button.clicked.connect(self.window_minimum)  # 设置点击的信号事件self.maximum_button.clicked.connect(self.window_maximum)self.close_button.clicked.connect(self.window_close)# 设置objectName来设置样式self.setObjectName('titleBar')self.minimum_button.setObjectName('minimumButton')self.maximum_button.setObjectName('maximumButton')self.close_button.setObjectName('closeButton')self.setStyleSheet("""#titleBar{background-color: rgb(34,102,175);}#minimumButton,#maximumButton,#closeButton {border: none;background-color: rgb(34,102,175);}#minimumButton:hover,#maximumButton:hover {color: rgb(33,165,229);}#closeButton:hover {color: rgb(200,49,61);}""")self.setLayout(layout)def mouseDoubleClickEvent(self, event):self.window_maximum()event.accept()  # 接受事件,禁止传到父控件# 鼠标移动def mouseMoveEvent(self, event):if event.buttons() == Qt.LeftButton and self._mouse_pos:self.parent().move(self.mapToGlobal(event.pos() - self._mouse_pos))event.accept()  # 接受事件,不传递到父控件def mousePressEvent(self, event):if event.button() == Qt.LeftButton:self._mouse_pos = event.pos()event.accept()  # 接受事件,不传递到父控件def mouseReleaseEvent(self, event):self._mouse_pos = Noneevent.accept()  # 接受事件,不传递到父控件def window_minimum(self):self.parent().showMinimized()def window_maximum(self):if self.maximum_button.text() == '1':self.maximum_button.setText('2')self.parent().showMaximized()else:self.maximum_button.setText('1')self.parent().showNormal()def window_close(self):self.parent().close()def set_window_title(self, title):self.title_text.setText(title)def set_window_icon(self, pix_map):if isinstance(pix_map, QPixmap):self.title_label.setPixmap(pix_map)class CenterWidget(QStackedWidget):def __init__(self, *args, **kwargs):super(CenterWidget, self).__init__(*args, **kwargs)self.setAutoFillBackground(True)def clear(self):for i in range(self.count()):widget = self.widget(i)self.removeWidget(widget)if widget is not None:widget.deleteLater()del widgetclass StatusBar(QStatusBar):def __init__(self, *args, **kwargs):super(StatusBar, self).__init__(*args, **kwargs)self.setAutoFillBackground(True)class FrameLessWindow(QWidget):"""主窗口"""MARGIN = 5Left, Top, Right, Bottom, LeftTop, RightTop, LeftBottom, RightBottom = range(8)def __init__(self, *args, **kwargs):super(FrameLessWindow, self).__init__(*args, **kwargs)self.resize(1200, 680)self.setWindowFlags(Qt.FramelessWindowHint)  # 无边框self.setAttribute(Qt.WA_TranslucentBackground, True)self.setMouseTracking(True)  # 鼠标追踪,mouseMoveEvent才有效果self._direction = None  # 此时鼠标的方向self._pressed = False  # 鼠标是否按下self._mouse_pos = None  # 记录鼠标位置layout = QVBoxLayout(self)layout.setSpacing(0)layout.setContentsMargins(QMargins(self.MARGIN, self.MARGIN, self.MARGIN, self.MARGIN))self.title = TitleBar(self)self.title.installEventFilter(self)  # 安装事件过滤,进入控件还原方向和鼠标状态layout.addWidget(self.title, alignment=Qt.AlignTop)self.center_widget = CenterWidget(self)self.center_widget.installEventFilter(self)layout.addWidget(self.center_widget)self.status_bar = StatusBar(self)self.status_bar.installEventFilter(self)layout.addWidget(self.status_bar, alignment=Qt.AlignBottom)self.setLayout(layout)def eventFilter(self, obj, event):if isinstance(event, QEnterEvent):self.setCursor(Qt.ArrowCursor)self._direction = None  # 去除方向self._pressed = None  # 去除按下标记return super(FrameLessWindow, self).eventFilter(obj, event)def mousePressEvent(self, event):super(FrameLessWindow, self).mousePressEvent(event)if event.button() == Qt.LeftButton:self._mouse_pos = event.pos()self._pressed = Truedef mouseReleaseEvent(self, event):super(FrameLessWindow, self).mouseReleaseEvent(event)self._pressed = Falseself._direction = Nonedef mouseMoveEvent(self, event):super(FrameLessWindow, self).mouseMoveEvent(event)pos = event.pos()pos_x, pos_y = pos.x(), pos.y()wm, hm = self.width() - self.MARGIN, self.height() - self.MARGIN# print(wm, hm)# 窗口最大无需事件if self.isMaximized() or self.isFullScreen():self._direction = Noneself.setCursor(Qt.ArrowCursor)returnif event.buttons() == Qt.LeftButton and self._pressed:self.resize_window(pos)if pos_x <= self.MARGIN and pos_y <= self.MARGIN:# 左上角self._direction = self.LeftTopself.setCursor(Qt.SizeFDiagCursor)elif wm <= pos_x <= self.width() and hm <= pos_y <= self.height():# 右下角self._direction = self.RightBottomself.setCursor(Qt.SizeFDiagCursor)elif wm <= pos_x and pos_y <= self.MARGIN:# 右上角self._direction = self.RightTopself.setCursor(Qt.SizeBDiagCursor)elif pos_x <= self.MARGIN and hm <= pos_y:# 左下角self._direction = self.LeftBottomself.setCursor(Qt.SizeBDiagCursor)elif 0 <= pos_x <= self.MARGIN <= pos_y <= hm:# 左边self._direction = self.Leftself.setCursor(Qt.SizeHorCursor)elif wm <= pos_x <= self.width() and self.MARGIN <= pos_y <= hm:# 右边self._direction = self.Rightself.setCursor(Qt.SizeHorCursor)elif wm >= pos_x >= self.MARGIN >= pos_y >= 0:# 上面self._direction = self.Topself.setCursor(Qt.SizeVerCursor)elif self.MARGIN <= pos_x <= wm and hm <= pos_y <= self.height():# 下面self._direction = self.Bottomself.setCursor(Qt.SizeVerCursor)else:passdef showMaximized(self):super(FrameLessWindow, self).showMaximized()self.layout().setContentsMargins(0, 0, 0, 0)def showNormal(self):super(FrameLessWindow, self).showNormal()self.layout().setContentsMargins(self.MARGIN, self.MARGIN, self.MARGIN, self.MARGIN)def paintEvent(self, event):super(FrameLessWindow, self).paintEvent(event)painter = QPainter(self)painter.setPen(QPen(QColor(200, 200, 200, 1), 2 * self.MARGIN))painter.drawRect(self.rect())def setWindowTitle(self, title):super(FrameLessWindow, self).setWindowTitle(title)self.title.set_window_title(title)def setWindowIcon(self, icon):if isinstance(icon, QIcon):super(FrameLessWindow, self).setWindowIcon(icon)self.title.set_window_icon(icon.pixmap(20, 20))def resize_window(self, pos):if self._direction is None:returnmpos = pos - self._mouse_posxPos, yPos = mpos.x(), mpos.y()geometry = self.geometry()x, y, w, h = geometry.x(), geometry.y(), geometry.width(), geometry.height()if self._direction == self.LeftTop:  # 左上角if w - xPos > self.minimumWidth():x += xPosw -= xPosif h - yPos > self.minimumHeight():y += yPosh -= yPoselif self._direction == self.RightBottom:  # 右下角if w + xPos > self.minimumWidth():w += xPosself._mouse_pos = posif h + yPos > self.minimumHeight():h += yPosself._mouse_pos = poselif self._direction == self.RightTop:  # 右上角if h - yPos > self.minimumHeight():y += yPosh -= yPosif w + xPos > self.minimumWidth():w += xPosself._mouse_pos.setX(pos.x())elif self._direction == self.LeftBottom:  # 左下角if w - xPos > self.minimumWidth():x += xPosw -= xPosif h + yPos > self.minimumHeight():h += yPosself._mouse_pos.setY(pos.y())elif self._direction == self.Left:  # 左边if w - xPos > self.minimumWidth():x += xPosw -= xPoselse:returnelif self._direction == self.Right:  # 右边if w + xPos > self.minimumWidth():w += xPosself._mouse_pos = poselse:returnelif self._direction == self.Top:  # 上面if h - yPos > self.minimumHeight():y += yPosh -= yPoselse:returnelif self._direction == self.Bottom:  # 下面if h + yPos > self.minimumHeight():h += yPosself._mouse_pos = poselse:returnself.setGeometry(x, y, w, h)def remove_status_bar(self):self.status_bar.hide()def set_center_widget(self, widget):self.center_widget.clear()self.center_widget.addWidget(widget)

PyQt5自定义无边框窗口相关推荐

  1. 【QT】自定义无边框窗口分享

    [QT/天下wu双]自定义无边框窗口分享 https://www.bilibili.com/video/BV1HA411Y7d4 源码链接:https://github.com/Bili-TianX/ ...

  2. Electron无边框窗口(最小化、最大化、关闭、拖动)以及动态改变窗口大小

    文章目录 一.目标原型 1. 目标 2. 原型设计 3. 原型初步实现 二.无边框窗口 1. 要点 2. 改造 三.可拖拽区 1. 要点 2. 改造 四.最小化.最大化.关闭 1. 要点 2. 改造 ...

  3. QT实现可移动和改变尺寸的无边框窗口

    2019独角兽企业重金招聘Python工程师标准>>> 实现QT无边框窗口的拖动,尺寸改变.需要的时候从该类继承,派生类需要定义为QWidget. 头文件: #ifndef SIZE ...

  4. [乱说]Electron 无边框窗口最大化最小化关闭功能

    title: '[乱说]Electron 无边框窗口最大化最小化关闭功能' date: 2017-11-21 21:43:40 tags: Electron 无边框窗口最大化最小化关闭功能 目的 实现 ...

  5. Qt Quick无边框窗口

    开发环境:Qt Creator 5.6 内容:  使用 Qt  Quick创建无边框窗口 Qt Quick是一个无比强大.无比方便快捷的跨平台的开发框架,并且能通过Qt强大的元对象系统实现qml与c+ ...

  6. 【C++·Qt】Qt透明无边框窗口以及拖动

    窗口透明  1.窗口整体透明(包含其子空控件) //窗口以及子控件都透明 //setAttribute(Qt::WA_WState_WindowOpacitySet); //网上说直接设置不起作用,需 ...

  7. QT实现完美无边框窗口(可拖动,可调整大小)

    效果如下: 只需定义 nativeEvent 事件即可完成这样的功能 ,但要注意的是,这是通过Windows api实现的. 样例如下:(注意头文件) framelesswidget.h #ifnde ...

  8. qt 全屏窗口有边框_如何在全屏无边框窗口模式下玩任何Windows游戏

    qt 全屏窗口有边框 If you're a regular PC gamer, you know that playing a game in full screen mode can someti ...

  9. Qt 暗夜黑主题教程(一) 创建带圆角和阴影的无边框窗口

    创建项目 创建一个主窗口为 QWidget 类.带 UI样式表的项目.我的项目名叫 NightDark,窗口类名叫 Widget,刚入门的小白可以跟我命名保持一致方便学习,大佬自便.(不对,大佬怎么来 ...

  10. 最简单的方式实现QML无边框窗口边缘拖动调整大小

    前言 使用Qt在开发桌面程序时,通常会去除默认的程序边框,从而实现自定义的标题栏.然而当设置窗口属性为Qt.FramelessWindowHint后,窗口的拖动,以及在边缘拖动缩放的功能就没有了,在以 ...

最新文章

  1. 为什么 CPU 访问硬盘很慢
  2. linux C库编译
  3. js可以放gif吗_你清楚,一瓶开过的葡萄酒,最长可以放多久的时间吗?
  4. Django创建项目的命令
  5. 网络分流器-网络分流器-网络安全评估探讨
  6. Oracle 发布基于 VS Code 的开发者工具,轻松连接 Oracle 数据库
  7. win10win键无反应_台式电脑开机主机没反应怎么办 电脑开机主机没反应解决【详解】...
  8. Exchange Server 2016 独立部署/共存部署 (六)—— 创建数据库副本
  9. 待起飞的の集训8.5
  10. Jsp 中taglib标签的妙用
  11. java 读写mysql_Java读写MySQL数据库小实例
  12. 设计模式之GOF23访问者模式
  13. 计算机软件资格好考吗,计算机软件资格辅导哪个好
  14. oracle公司财务管理课程设计,Oracle财务管理系统培训手册—资产模块(FA).doc
  15. linux关机会自动重启,linux——如何在linux下让系统定时自动重启(关机)
  16. Git 从入门到放不下
  17. 创建手工凭证实现分录中原币=0本位币<>0的效果-FBB1
  18. Excel VBA 金融建模 培训
  19. 合同相似可逆等价矩阵的关系及性质_矩阵的合同,等价与相似的联系与区别.doc...
  20. [10] JMeter-察看结果树,你知道都有哪些功能吗?

热门文章

  1. 大学计算机基础超详细知识点(高手总结),大学计算机基础超详细知识点(高手总结)免费-...
  2. Windows里面比较好用的在线读书笔记软件
  3. 高通量数据中批次效应的鉴定和处理 - 系列总结和更新
  4. Cannot find current proxy: Set ‘exposeProxy‘ property on Advised to ‘true‘ to make it available,and.
  5. 秀米排版,从入门到入土(一)
  6. 基于Android点菜系统的设计与实现,基于Android的手机点菜系统的设计与实现论文.doc...
  7. 修改ipa文件版本号
  8. 如何通过网络遥测(Network Telemetry)技术实现精细化网络运维
  9. 【c++】c++基础入门
  10. 三菱FX5U系列PLC中的DSZR机械原点回归指令(带DOG搜索)的详细分析