网站首页 > 技术文章 正文
通过本文章,可以掌握以下内容:
- QMainWindow布局
- QMainWindow常用属性和方法介绍
- QMainWindow图标和背景设置
- QMainWindow无边框设计实现
1、QMainWindow布局
主窗口提供了用于构建应用程序的用户界面的框架,其主要布局如下
- Menu Bar:菜单栏,通过添加QMenuBar
# 实例化QMenuBar
self.menuBarInstance = QMenuBar(self)
# 创建菜单
fileMenu = self.menuBarInstance.addMenu("文件")
# 创建动作
exitAction = QAction("退出", self)
exitAction.triggered.connect(self.close)
# 将动作添加到菜单
fileMenu.addAction(exitAction)
- Toolbars:工具栏,通过往窗口添加QToolBar
# 实例化QToolBar
toolBar = QToolBar("我的工具栏", self)
self.addToolBar(toolBar)
# 创建动作
exitAction = QAction("退出", self)
exitAction.triggered.connect(self.close)
# 将动作添加到菜单
fileMenu.addAction(exitAction)
- Dock Widgets:停靠部件,比如浮窗的拖动部件,通过往窗口添加QDockWidgets
# 创建一个QDockWidget
dock = QDockWidget("菜单", self)
self.addDockWidget(Qt.LeftDockWidgetArea, dock)
# 创建一个列表作为菜单项容器
menuList = QListWidget()
dock.setWidget(menuList)
- Central Widget:占据主窗口中心区域的部件,通常是标准 Qt 小部,通过添加Widget部件
# 实例化一个QWidget作为中心部件
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
# 创建一个布局
layout = QVBoxLayout()
# 添加一些控件到布局中
layout.addWidget(QLabel("这是一个标签"))
# 将布局设置给中心部件
centralWidget.setLayout(layout)
- Status Bar:状态栏显示,通过添加QStatusBar
# 实例化一个QStatusBar
statusBar = QStatusBar()
# 将状态栏设置为主窗口的状态栏
self.setStatusBar(statusBar)
# 在状态栏中添加一些信息
statusBar.addWidget(QLabel("这是状态栏信息"))
2、QMainWindow常用属性和方法
属性
- windowTitle::窗口的标题。
- menuBar:窗口的菜单栏。
- statusBar:窗口的状态栏。
- centralWidget:窗口的中心部件。
- toolBars:窗口的工具栏列表。
- dockWidgets:窗口的停靠窗口列表。
- animated:操作停靠小部件和工具栏是否有动画
- dockNestingEnabled:停靠部件是否可以嵌套
- dockOptions:QMainWindow的停靠行为
- documentMode:选项卡式停靠小部件的选项卡栏是否设置为文档模式
- iconSize:此主窗口中工具栏图标的大小
- tabShape:用于选项卡式停靠小部件的选项卡形状
- toolButtonStyle:主窗口中工具栏按钮的样式
- unifiedTitleAndToolBarOnMac:窗口是否在macOS上使用统一的标题和工具栏外观
方法
- setWindowFlags(Qt.WindowFlags flags):用于指定窗口的各种属性和行为。例如,你可以设置窗口为无边框、始终在顶层显示、不显示在任务栏等
窗口装饰标志 | |
Qt.MSWindowsFixedSizeDialogHint | Windows平台上,使对话框窗口的大小固定,不能被用户调整。 |
Qt.X11BypassWindowManagerHint | 在X11平台(Linux/Unix)上,使窗口绕过窗口管理器,直接与系统交互。这通常用于需要完全控制窗口显示和行为的特殊窗口 |
Qt.FramelessWindowHint | 创建一个无边框窗口。这通常用于自定义窗口的外观。 |
Qt.NoDropShadowWindowHint | 禁用窗口的阴影效果。这在自定义窗口绘制时可能有用,特别是在需要精确控制窗口外观的情况下。 |
Qt.WindowTitleHint | 窗口将包含一个标题栏。这是大多数窗口的默认行为。 |
Qt.WindowSystemMenuHint | 窗口将包含一个系统菜单,通常位于标题栏的左上角。 |
Qt.WindowMinimizeButtonHint | 窗口将包含一个最小化按钮。 |
Qt.WindowMaximizeButtonHint | 窗口将包含一个最大化按钮。 |
Qt.WindowCloseButtonHint | 窗口将包含一个关闭按钮。 |
Qt.WindowContextHelpButtonHint | 窗口将包含一个上下文帮助按钮,在用户点击时通常会显示帮助信息。 |
Qt.WindowStaysOnTopHint | 窗口将始终保持在其他窗口之上。 |
Qt.WindowStaysOnBottomHint | 窗口将始终保持在其他窗口之下。 |
Qt.CustomizeWindowHint | 允许窗口被自定义,通常与其他窗口标志一起使用,以提供特定的窗口外观和行为。 |
常用窗口标志 | |
Qt.Widget | 默认值,指示对象是一个控件 |
Qt.Window | 使控件成为一个窗口,这会给它提供窗口装饰 |
Qt.Dialog | 示窗口是一个对话框 |
Qt.Sheet | 指示窗口是一个Mac风格的表单(仅在Mac OS X中有效) |
Qt.Drawer | 指示窗口是一个Mac风格的抽屉(仅在Mac OS X中有效) |
Qt.Popup | 指示窗口是一个弹出窗口 |
Qt.Tool | 指示窗口是一个工具窗口。工具窗口是一个小窗口,通常用于提供模式或非模式对话框 |
Qt.ToolTip | 指示窗口是一个工具提示 |
Qt.SplashScreen | 指示窗口是一个启动画面 |
Qt.Desktop | 指示窗口是桌面。这是一个特殊的窗口,不能创建 |
Qt.SubWindow | 指示窗口是一个子窗口 |
- addDockWidget(area, dockwidget, orientation): 在指定区域和方向添加一个停靠窗口。以下是停靠的枚举值
常用的停靠窗口标志 | |
QMainWindow.AnimatedDocks | 与属性相同animated。 |
QMainWindow.AllowNestedDocks | 与属性相同dockNestingEnabled。 |
QMainWindow.AllowTabbedDocks | 用户可以将一个停靠小部件放置在另一个停靠小部件的“顶部”。这两个小部件堆叠在一起,并出现一个选项卡栏,用于选择哪个小部件可见。 |
QMainWindow.ForceTabbedDocks | 每个停靠区域都包含一堆选项卡式停靠小部件。换句话说,停靠小部件不能在停靠区域中彼此相邻放置。如果设置此选项,AllowNestedDocks 不起作用。 |
QMainWindow.VerticalTabs | 主窗口两侧的两个垂直停靠区域垂直显示其选项卡。如果未设置此选项,所有停靠区域都会在底部显示其选项卡。暗示AllowTabbedDocks。也可以看看setTabPosition()。 |
QMainWindow.GroupedDragging | 拖动扩展坞的标题栏时,所有与其关联的选项卡都将被拖动。暗示AllowTabbedDocks。如果某些 QDockWidget 在允许的区域有限制,则效果不佳。(这个枚举值是在 Qt 5.6 中添加的。) |
- addDockWidget(area, dockwidget): 在指定区域添加一个停靠窗口。
- addToolBar(area, toolbar): 在指定区域添加一个工具栏。
- addToolBar(title): 创建一个新的工具栏,使用提供的标题。
- addToolBar(toolbar): 添加一个预先创建的工具栏。
- addToolBarBreak([area=Qt.TopToolBarArea]): 在指定区域添加一个工具栏断点。
- centralWidget(): 返回当前设置为中心部件的QWidget对象。
- corner(corner): 返回指定角落的停靠区域。
- dockOptions(): 返回当前的停靠选项。
- dockWidgetArea(dockwidget): 返回指定停靠窗口所在的区域。
- documentMode(): 返回文档模式的启用状态。
- iconSize(): 返回工具栏图标的大小。
- insertToolBar(before, toolbar): 在指定的工具栏之前插入一个工具栏。
- insertToolBarBreak(before): 在指定的工具栏之前插入一个工具栏断点。
- isAnimated(): 返回窗口是否启用动画。
- isDockNestingEnabled(): 返回是否允许停靠窗口嵌套。
- isSeparator(pos): 检查指定位置是否为分隔符。
- menuBar(): 返回窗口的菜单栏。
- menuWidget(): 返回设置为菜单栏的自定义QWidget对象。
- removeDockWidget(dockwidget): 移除指定的停靠窗口。
- removeToolBar(toolbar): 移除指定的工具栏。
- removeToolBarBreak(before): 移除指定位置的工具栏断点。
- resizeDocks(docks, sizes, orientation): 调整一组停靠窗口的大小。
- restoreDockWidget(dockwidget): 恢复停靠窗口的状态。
- restoreState(state[, version=0]): 恢复窗口的状态。
- saveState([version=0]): 保存窗口的当前状态。
- setCentralWidget(widget): 设置中心部件。
- setCorner(corner, area): 设置窗口角落的停靠区域。
- setDockOptions(options): 设置停靠选项。
- setDocumentMode(enabled): 启用或禁用文档模式。
- setIconSize(iconSize): 设置工具栏图标的大小。
- setMenuBar(menubar): 设置窗口的菜单栏。
- setMenuWidget(menubar): 设置自定义的菜单栏部件。
- setStatusBar(statusbar): 设置窗口的状态栏。
- setTabPosition(areas, tabPosition): 设置停靠窗口的标签位置。
- setTabShape(tabShape): 设置停靠窗口的标签形状。
- setToolButtonStyle(toolButtonStyle): 设置工具按钮的样式。
- splitDockWidget(after, dockwidget, orientation): 将一个停靠窗口分割为两个。
- statusBar(): 返回窗口的状态栏。
- tabPosition(area): 返回指定区域的标签位置。
- tabShape(): 返回停靠窗口的标签形状。
- tabifiedDockWidgets(dockwidget): 返回与指定停靠窗口标签化的所有停靠窗口。
- tabifyDockWidget(first, second): 将两个停靠窗口标签化。
- takeCentralWidget(): 移除并返回中心部件。
- toolBarArea(toolbar): 返回指定工具栏所在的区域
- toolBarBreak(toolbar): 检查指定工具栏之前是否有工具栏断点。
- toolButtonStyle(): 返回工具按钮的样式。
- unifiedTitleAndToolBarOnMac(): 返回是否在Mac OS上使用统一的标题栏和工具栏样式。
- createPopupMenu(): 创建一个包含所有可停靠窗口和工具栏的可见性控制项的弹出菜单。这个方法通常用于提供一个上下文菜单,允许用户选择哪些工具栏或停靠窗口是可见的。
3、QMainWindow图标和背景设置
设置logo图标
# 设置窗口图标
self.setWindowIcon(QIcon('path/to/your/icon.png'))
设置背景
- 通过样式设置颜色
# 使用样式表设置背景颜色
self.setStyleSheet("background-color: lightblue;")
- 通过样式设置图片
# 使用样式表设置背景图片
self.setStyleSheet("background-image: url('path/to/your/image.jpg');")
- 通过QPainter绘制背景图片
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("通过paintEvent设置背景")
def paintEvent(self, event):
painter = QPainter(self)
pixmap = QPixmap("path/to/your/image.jpg")
P·ainter.drawPixmap(self.rect(), pixmap)
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
4、QMainWindow无边框设计实现
实现无边框设计,pyside6目前没有很好的解决方案。主要思路是设置无边框,通过自定义标题栏来实现窗口的基本属性,事件。下面是具体例子:
from PySide6.QtCore import QSize, Qt, QEvent
from PySide6.QtGui import QPalette, QRegion
from PySide6.QtWidgets import *
class CustomTitleBar(QWidget):
def __init__(self, parent):
super().__init__(parent)
self.setAutoFillBackground(True)
self.setBackgroundRole(QPalette.ColorRole.Highlight)
self.initial_pos = None
title_bar_layout = QHBoxLayout(self)
title_bar_layout.setContentsMargins(1, 1, 1, 1)
title_bar_layout.setSpacing(2)
self.title = QLabel("自定义工具栏", self)
self.title.setStyleSheet(
"""font-weight: bold;
border: 2px solid black;
border-radius: 12px;
margin: 2px;
"""
)
self.title.setAlignment(Qt.AlignmentFlag.AlignCenter)
if title := parent.windowTitle():
self.title.setText(title)
# 只设置自定义标题拖动
self.title.mousePressEvent = parent.title_mousePressEvent
self.title.mouseMoveEvent = parent.title_mouseMoveEvent
self.title.mouseReleaseEvent = parent.title_mouseReleaseEvent
title_bar_layout.addWidget(self.title)
# Min button
self.min_button = QToolButton(self)
min_icon = self.style().standardIcon(
QStyle.StandardPixmap.SP_TitleBarMinButton
)
self.min_button.setIcon(min_icon)
self.min_button.clicked.connect(self.window().showMinimized)
# Max button
self.max_button = QToolButton(self)
max_icon = self.style().standardIcon(
QStyle.StandardPixmap.SP_TitleBarMaxButton
)
self.max_button.setIcon(max_icon)
self.max_button.clicked.connect(self.window().showMaximized)
# Close button
self.close_button = QToolButton(self)
close_icon = self.style().standardIcon(
QStyle.StandardPixmap.SP_TitleBarCloseButton
)
self.close_button.setIcon(close_icon)
self.close_button.clicked.connect(self.window().close)
# Normal button
self.normal_button = QToolButton(self)
normal_icon = self.style().standardIcon(
QStyle.StandardPixmap.SP_TitleBarNormalButton
)
self.normal_button.setIcon(normal_icon)
self.normal_button.clicked.connect(self.window().showNormal)
self.normal_button.setVisible(False)
# Add buttons
buttons = [
self.min_button,
self.normal_button,
self.max_button,
self.close_button,
]
for button in buttons:
button.setFocusPolicy(Qt.FocusPolicy.NoFocus)
button.setFixedSize(QSize(28, 28))
button.setStyleSheet(
"""QToolButton { border: 2px solid white;
border-radius: 12px;
}
"""
)
title_bar_layout.addWidget(button)
def window_state_changed(self, state):
if state == Qt.WindowState.WindowMaximized:
self.normal_button.setVisible(True)
self.max_button.setVisible(False)
else:
self.normal_button.setVisible(False)
self.max_button.setVisible(True)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Custom Title Bar")
self.setMinimumSize(600, 400)
self.setWindowFlags(Qt.FramelessWindowHint)
# 使用QSS设置边框样式为圆角
self.setStyleSheet("MainWindow{border-radius: 1px;}")
central_widget = QWidget()
self.title_bar = CustomTitleBar(self)
work_space_layout = QVBoxLayout()
work_space_layout.setContentsMargins(11, 11, 11, 11)
work_space_layout.addWidget(QLabel("Hello, World!", self))
centra_widget_layout = QVBoxLayout()
centra_widget_layout.setContentsMargins(0, 0, 0, 0)
centra_widget_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
centra_widget_layout.addWidget(self.title_bar)
centra_widget_layout.addLayout(work_space_layout)
central_widget.setLayout(centra_widget_layout)
self.setCentralWidget(central_widget)
def changeEvent(self, event):
if event.type() == QEvent.Type.WindowStateChange:
self.title_bar.window_state_changed(self.windowState())
super().changeEvent(event)
event.accept()
def window_state_changed(self, state):
self.normal_button.setVisible(state == Qt.WindowState.WindowMaximized)
self.max_button.setVisible(state != Qt.WindowState.WindowMaximized)
def title_mousePressEvent(self, event):
if event.button() == Qt.MouseButton.LeftButton:
self.initial_pos = event.position().toPoint()
super().mousePressEvent(event)
event.accept()
def title_mouseMoveEvent(self, event):
if self.initial_pos is not None:
delta = event.position().toPoint() - self.initial_pos
self.window().move(
self.window().x() + delta.x(),
self.window().y() + delta.y(),
)
super().mouseMoveEvent(event)
event.accept()
def title_mouseReleaseEvent(self, event):
self.initial_pos = None
super().mouseReleaseEvent(event)
event.accept()
if __name__ == "__main__":
app = QApplication([])
window = MainWindow()
window.show()
app.exec()
效果如下,可以实现放大,缩小,标题栏拖动功能:
上面例子没有实现窗口边框可拖动放大缩小的功能,是个遗憾。github上的有实现,可以参考:https://github.com/alexpdev/QtFrameless。
- 上一篇: Qt图形视图、动画框架 qt图形
- 下一篇: 开启灵活开发编码模式:规则引擎drools——规则属性
猜你喜欢
- 2024-12-24 Excel VBA 用户窗体设置/一步一步代你设计EXCEL用户+密码登录界面
- 2024-12-24 家庭收支理财管理系统 Access数据库系统课程设计制作实例
- 2024-12-24 Qt 2D绘图:图形视图框架的事件处理与传播
- 2024-12-24 MFC界面库BCGControlBar v32.1 - 可视化管理器和主题升级
- 2024-12-24 DJYGUI系列文章九:GDD消息系统 gd信息
- 2024-12-24 Qt设备识别(简单的密钥生成器) qt设备管理系统
- 2024-12-24 Access开发的《财务经济管理系统》
- 2024-12-24 初级开发人员告诉我:OO 设计模式太复杂而且没用
- 2024-12-24 从零开始学Qt(89):UDP单播和广播
- 2024-12-24 Qt入门阶段之事件 qtc间期延长的临床意义
- 02-21走进git时代, 你该怎么玩?_gits
- 02-21GitHub是什么?它可不仅仅是云中的Git版本控制器
- 02-21Git常用操作总结_git基本用法
- 02-21为什么互联网巨头使用Git而放弃SVN?(含核心命令与原理)
- 02-21Git 高级用法,喜欢就拿去用_git基本用法
- 02-21Git常用命令和Git团队使用规范指南
- 02-21总结几个常用的Git命令的使用方法
- 02-21Git工作原理和常用指令_git原理详解
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)