Vulpine 发表于 2024-4-28 19:04

求教关于pyside6/pyqt自定义标题的问题

本帖最后由 Vulpine 于 2024-4-28 19:28 编辑

PyQt5 自定义标题栏,实现无边框,最小化最大化关闭事件,窗口拖动移动,窗口改变大小,仿百度网盘色调美化_pyqt设置主窗口标题栏的颜色-CSDN博客
我按照这个教程去实现自定义标题栏和重写鼠标事件以支持鼠标拖动窗口边缘缩放,但是遇到一个问题就是在鼠标拖动窗口边缘缩放时并不如保留系统窗口标题栏时的缩放那么流畅,甚至会看到缩放的过程中窗口存在卡顿现象。但是如果保留系统窗口标题的话又不能过多地修改标题栏。
经过询问gpt,只能按照如下代码修改系统标题栏为深色:
import ctypes
from ctypes import wintypes

from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton

# 定义 HRESULT
HRESULT = ctypes.c_long

# 导入必要的 Windows 库
user32 = ctypes.windll.user32
dwmapi = ctypes.windll.dwmapi

# 常量定义
DWMWA_USE_IMMERSIVE_DARK_MODE = 20

# 函数原型声明
dwmapi.DwmSetWindowAttribute.argtypes = [
    wintypes.HWND, wintypes.DWORD, wintypes.LPCVOID, wintypes.DWORD
]
dwmapi.DwmSetWindowAttribute.restype = HRESULT


class MainWindow(QMainWindow):
    def __init__(self):
      super().__init__()
      self.setWindowTitle("Custom Title Bar Color with Windows API")
      self.setGeometry(100, 100, 400, 300)
      self.init_ui()

    def init_ui(self):
      # 添加一个按钮来关闭窗口
      close_button = QPushButton('Close', self)
      close_button.clicked.connect(self.close)
      close_button.move(150, 130)

    def set_title_bar_color(self, dark):
      """设置窗口标题栏为深色或浅色模式"""
      # 获取当前窗口的 HWND
      hwnd = self.winId()

      # 把 Python 的 bool 转换为 Windows BOOL 类型(整数)
      is_dark_mode = ctypes.c_int(dark)

      # 调用 DwmSetWindowAttribute
      result = dwmapi.DwmSetWindowAttribute(
            ctypes.c_void_p(int(hwnd)),# HWND 需要转换为正确的类型
            DWMWA_USE_IMMERSIVE_DARK_MODE,
            ctypes.byref(is_dark_mode),
            ctypes.sizeof(is_dark_mode)
      )
      if result != 0:
            raise ctypes.WinError(result)

    def showEvent(self, event):
      super().showEvent(event)
      self.set_title_bar_color(True)


if __name__ == '__main__':
    app = QApplication([])
    window = MainWindow()
    window.show()
    app.exec()

https://s2.loli.net/2024/04/28/Yuzclgy4bRnPsN7.png
因为我的软件界面主要是深色的,所以只需要修改标题栏颜色为深色也能勉强看得过去,但是会有限制,win7无法使用,gpt上说这个常量DWMWA_USE_IMMERSIVE_DARK_MODE = 20仅适用于 Windows 11 Build 22000 及以后的版本。在 Windows 7 或更早的版本中,不支持此常量。但是这样的话想过多的自定义标题栏时好像是做不到的。
这样就进入进退两难的地步,请问大佬有没有既能自定义标题栏,又能鼠标拖动窗口边缘缩放时不卡顿,甚至可以像保留系统窗口标题栏时的缩放那样流畅。

天轩科技 发表于 2024-4-28 20:27

尝试做个判断? 不是win11用常规的标题栏,如果是win11系统就自定义标题栏?

Vulpine 发表于 2024-4-28 21:20

天轩科技 发表于 2024-4-28 20:27
尝试做个判断? 不是win11用常规的标题栏,如果是win11系统就自定义标题栏?

谢谢回答,这个软件是在win7上运行的,所以也是没办法了{:1_907:}

天轩科技 发表于 2024-4-28 22:47

Vulpine 发表于 2024-4-28 21:20
谢谢回答,这个软件是在win7上运行的,所以也是没办法了

win7就算了吧。用常规就行。节省点代码

爱飞的猫 发表于 2024-4-29 06:33

Vulpine 发表于 2024-4-28 21:20
谢谢回答,这个软件是在win7上运行的,所以也是没办法了

Win7 已经停止支援了,QT 6 也未将 Win7 列为支持的平台列表内。换句话说,QT 6 的态度就是如果在 Win7 上能跑起来,那你就用;但如果不能用或遇到问题,他们是不会修的:https://doc.qt.io/qt-6/windows.html#supported-configurations

如果你需要在 Win7 下运行,最好还是降级到 QT5。

v.n.lee 发表于 2024-4-29 08:49

试试qfluentwidgets

Vulpine 发表于 2024-4-30 00:12

爱飞的猫 发表于 2024-4-29 06:33
Win7 已经停止支援了,QT 6 也未将 Win7 列为支持的平台列表内。换句话说,QT 6 的态度就是如果在 Win7...

感谢版主回复。是的,我也打算切换回pyside2。win7下也能用PySide6.1.3,但实际上是个阉割版的pyside6,实测发现缺少需要用到的QtWebEngineWidgets模块,而pyside2是有的。

Vulpine 发表于 2024-4-30 00:31

v.n.lee 发表于 2024-4-29 08:49
试试qfluentwidgets

谢谢回复。我之前看了这个,支持qt5、6。效果还没试过,但是明显的缺点是收费{:1_907:}

v.n.lee 发表于 2024-4-30 08:45

Vulpine 发表于 2024-4-30 00:31
谢谢回复。我之前看了这个,支持qt5、6。效果还没试过,但是明显的缺点是收费

免费的啊,收费的是他自己改造的设计师

liwind 发表于 2024-5-3 00:16

PySide2-Frameless-Window这个是GPL的,只有无边框窗体。
页: [1] 2
查看完整版本: 求教关于pyside6/pyqt自定义标题的问题