PySide6-QML-无边框窗口那些事(一)

2021年12月30日 15158点热度 0人点赞 0条评论

之前一直想接触qt,因为python的GUI开发能选择的并不多,一些平常自用的就thinker几行代码就解决了。也是赶上再油管看到一个QML相关的视频,感觉挺有意思就"试逝"。

为什么要无边框窗口

  1. 是qt跨平台,想要统一窗口设计就必然要走这一步
  2. 系统自带的标题栏和控制按钮感觉比较一般

其实主要就是标题栏比较违和,系统标题栏颜色没办法直接修改。所以不管是用什么语言编写的GUI几乎都是先创建无边框的窗口,然后去自定义标题栏以及最大化最小化等那些控制按钮。

为什么要用QML(Qt Quick)

  1. 趋势吧,QT4开始也一直在向这方面在发展
  2. 可以用JS进行编程,许多界面的操作逻辑在qml就可以解决了

但是基础组件,比如 Qt Widget 这种更成熟。而我最终选择了QML的原因就是他和JS语言类似,当然底层也是V8那套东西。上一个UI是用electron写的,要处理html、js、css等等。而且一些功能是用python写的,两个不同的语言交互如果没有官方库支持,还是有些困难的。

要解决的问题

离不开窗口的基础操作,最大化最小化、拖动、缩放、以及在Windows上的窗口特效。文章中就不详细展示代码了,测试使用的代码可以以下连接中查看。

GitHub: https://github.com/Virace/pyside6-qml-frameless-window
Gitee: https://gitee.com/Virace/pyside6-qml-frameless-window

窗口控制

基础操作qml就可以解决了,文档: https://doc.qt.io/qt-6/qwindow.html#startSystemMove。比如说窗口拖动,就在你自建的标题栏或其他位置加上一下代码即可。

DragHandler {
            onActiveChanged: if (active) {
                                 mainWindow.startSystemMove()

                             }
        }

其中“mainWindow”, 是你得Windows类的ID名称,需要更换成自己的。

通过不断地了解QML文档,发现其实很多功能其自身就可以做到。但是问题也有很多,比如说窗口边缘用鼠标缩放窗口的问题,官方是给了函数的,文档: https://doc.qt.io/qt-6/qwindow.html#startSystemResize。但是实际使用问题很多,包括调用Windows API边缘缩放功能也会有这种问题。

窗口边缘拖动卡顿

看到的这个动图并没有慢放,而是 拖动时回出现的这种不跟鼠标的情况。目前没找到解决方法,stackoverflow中也有相同问题也是没有解决方法,但下面有回复说程序越复杂性能越好,也就是越复杂约不容易出现图中的问题。因为对Windows API的不了解导致对这一现象不理解~~~

而且经过测试似乎只是开启这个亚克力效果之后才会有这个问题。

窗口特效

这里只处理Windows上的效果,其它系统因为1是没有实际相关使用的系统,2是目前也没有跨平台的打算。

其实已经有关于QT已经有现成的轮子了,但是只有pyqt的,有关于pyside的内容还是比较少的,但pyqt毕竟是商业程序想商用是需要付费的,但是其实际代码是很相似的,不少也是可以通用的。

比如关于特效相关代码就来自于: https://github.com/zhiyiYo/PyQt-Frameless-Window

只需要再合适的位置调用即可,但与pyqt唯一不同的就是需要在 addWindowAnimation 方法中结尾添加以下内容

style = win32gui.GetWindowLong(hWnd, win32con.GWL_EXSTYLE)
style &= ~win32con.WS_EX_LAYERED
win32gui.SetWindowLong(
    hWnd,
    win32con.GWL_EXSTYLE,
    style
)

这是通过Spy++这个Visual Stuido 提供的程序,分析上原作者的代码以及自己测试使用的pyside6环境的窗口,其区别就是 多了个 WS_EX_LAYERED ,查了一下微软文档,就是这是一个封层窗口的意思。不清楚原理也不清楚什么意思,只不过窗口加上了这个窗口样式后,关闭特效就有了。

总结

花了三天时间来处理这些不同的东西,尝试去了解其中的原理,最后还是放弃了思考,解决问题是根本!

这个查找的过程是十分的难受的,这也是我这种学习方法的弊端吧,先不了解基础而是直接上手写一个项目,可能个人感觉这种方法更好吧~~~

文章评论