添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

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)