You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
By clicking “Sign up for GitHub”, you agree to our
terms of service
and
privacy statement
. We’ll occasionally send you account related emails.
Already on GitHub?
Sign in
to your account
在用PyQt实现无边框带阴影的窗体时,用到了两种方式,分别都遇到了Bug,请帮忙看下:
方案1 Bug
采用Qt实现阴影, 具体代码如库中
NewFramelessWindow.py
, 此方案有个Bug:点击标题栏,整个窗体会失去对鼠标的响应,例如按钮悬停等状态不会更新。然后如果拖动一下窗体,或者单击一下标题栏之外的区域,界面对鼠标的相应又会恢复正常。
方案2 Bug
采用实现实现nativeEvent方式,采用Window系统实现阴影,拦截
WM_NCCALCSIZE
事件隐藏标题栏。参考链接
QT自绘标题和边框
和
NativeEvent python demo
。
此方案的bug是多屏的副屏中,无论鼠标在哪,总是在resize箭头光标的状态,不能点击任何控件和拖动,在主屏上就没有问题。前面参考1中已经提到这个问题,但是我对C++编程和Windows这些API不太懂,能否麻烦给个下列副屏问题的python的实现方式?
当程序在辅屏上时,它的screen是辅屏,如果当前screen不等于QGuiApplication::primaryScreen(主屏),则不设置MINMAXINFO结构,但是由于它已经处理了WM_GETMINMAXINFO消息,导致这个消息不会被系统默认的窗口处理函数处理(DefWindowProc),所以才会显示不完整,解决办法是优先响应WM_GETMINMAXINFO消息,让后交给系统默认的窗口处理函数进行处理。
另外方案2中的全屏时显示不全问题,我没有用看懂文中C++代码中实现最大化时添加margin的方式,但是我仿照方案1中,用qt的changeEvent实现最大化添加了margin,也能解决问题。只是这个margin的值是试出来的,让窗体刚好全屏,具体应该设置多少从哪里看不清楚。
case WM_GETMINMAXINFO:
if (::IsZoomed(msg->hwnd)) {
// 最大化时会超出屏幕,所以填充边框间距
RECT frame = { 0, 0, 0, 0 };
AdjustWindowRectEx(&frame, WS_OVERLAPPEDWINDOW, FALSE, 0);
frame.left = abs(frame.left);
frame.top = abs(frame.bottom);
this->setContentsMargins(frame.left, frame.top, frame.right, frame.bottom);
else {
this->setContentsMargins(2, 2, 2, 2);
*result = ::DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
return true;
def changeEvent(self, event):
"""窗口状态改变
:param event:
# 窗口状态改变时修改标题栏控制按钮
if event.type() == 105: # WindowStateChange
if self.isMaximized():
self.gridLayout_3.setContentsMargins(10, 10, 10, 10) # 这个margin设多少?全屏显示不全,超出屏幕的尺寸具体是多少?
else:
self.gridLayout_3.setContentsMargins(0, 0, 0, 0)