PyQt 在Windows下实现类似Linux窗口界面

参考:

如何在pyqt中在实现无边框窗口的同时保留Windows窗口动画效果(一)

效果:

缺点:左右上靠边最大化/1/2化未实现,上层边框的圆角

思路:

通过paintEvent重写阴影和边框(即灰色部分),再使用QPushButton设置QSS为圆形放置在右上角

paintEvent部分代码:

        def paintEvent(self, event):
            # 阴影
            path = QPainterPath()
            path.setFillRule(Qt.WindingFill)

            pat = QPainter(self)
            pat.setRenderHint(pat.Antialiasing)
            pat.fillPath(path, QBrush(Qt.white))

            color = QColor(192, 192, 192, 50)

            for i in range(10):
                i_path = QPainterPath()
                i_path.setFillRule(Qt.WindingFill)
                ref = QRectF(10-i, 10-i, self.width()-(10-i)*2, self.height()-(10-i)*2)
                # i_path.addRect(ref)
                i_path.addRoundedRect(ref, self.border_width, self.border_width)
                color.setAlpha(150 - i**0.5*50)
                pat.setPen(color)
                pat.drawPath(i_path)

            # 圆角
            pat2 = QPainter(self)
            pat2.setRenderHint(pat2.Antialiasing)  # 抗锯齿
            pat2.setBrush(Qt.white)
            pat2.setPen(Qt.transparent)

            rect = self.rect()
            rect.setLeft(9)
            rect.setTop(9)
            rect.setWidth(rect.width()-9)
            rect.setHeight(rect.height()-9)
            pat2.drawRoundedRect(rect, 4, 4)

            #上层边框
            pat3 = QPainter(self)
            pat3.setRenderHint(pat3.Antialiasing)
            pat3.setBrush(QColor(231,234,237,255))
            pat3.setPen(Qt.transparent)
            rect2 = QRect(9, 9, self.width() - 18, 36)
            pat3.drawRoundedRect(rect2, 4, 4)

            for i in self.repaint:
                i()Code language: PHP (php)

最后for i in self,repaint: i()处是当窗口缩放时可以通过在__init__声明重绘函数列表再添加函数进去

即可实现自适应

下面是调用中的部分代码(框架原因,你们可能看不懂)

def maxWindowChange(ev):
    global maxiWindow, maxiBefore, win
    if not maxiWindow:
        maxiBefore = win.win.geometry()
        maxiWindow = True
        print(maxiBefore)
        win.showMaxi()
    else:
        maxiWindow = False
        win.win.setWindowState(qk.Qt.WindowNoState)
        win.win.setGeometry(maxiBefore)
def resetMaxiWindow():
    global maxiWindow
    maxiWindow = False

win.setNoWindowFrame()


closeBtn = qk.Button(win, text = '', width=20, height=20, click=win.win.close)
closeBtn.place(win.win.width()-25-36, -28)
closeBtn.setQSS("QPushButton{background-color:red;border-style:none;border-radius:10px;}")
closeBtn.setQSS("QPushButton:hover{background-color:#e60000;}")
closeBtn.setQSS("QPushButton:pressed{background-color:#d60000;}")


MaxBtn = qk.Button(win, text = '', width=20, height=20, click=maxWindowChange)
MaxBtn.place(win.win.width()-25-36-25, -28)
MaxBtn.setQSS("QPushButton{background-color:#f8ff78;border-style:none;border-radius:10px;}")
MaxBtn.setQSS("QPushButton:hover{background-color:#ced900;}")
MaxBtn.setQSS("QPushButton:pressed{background-color:#bac400;}")

MinBtn = qk.Button(win, text = '', width=20, height=20, click=win.showMini)
MinBtn.place(win.win.width()-25-36-25-25, -28)
MinBtn.setQSS("QPushButton{background-color:#0fe800;border-style:none;border-radius:10px;}")
MinBtn.setQSS("QPushButton:hover{background-color:#13c406;}")
MinBtn.setQSS("QPushButton:pressed{background-color:#14990b;}")


test = qk.Button(win, text='Hello World!', width=120)
test.place(0, 0)
        

win.repaint.append(lambda:closeBtn.place(win.win.width()-25-36, -28))
win.repaint.append(lambda:MaxBtn.place(win.win.width()-25-36-25, -28))
win.repaint.append(lambda:MinBtn.place(win.win.width()-25-36-25-25, -28))Code language: PHP (php)

可以主要参考最大化最小化关闭按钮的QSS

发表回复