BoxLayout 的 PyQt 框架

问题描述

我现在被困了 2 个多小时,试图在我的 Boxlayout 周围放置一个框架/边框。

这是主要的最小 Main.py

from PyQt5 import QtGui
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import circle


class fenster(QWidget):

    def __init__(self):
        super().__init__()

        self.top = 100
        self.left = 100
        self.width = 900
        self.height = 1200

        self.initMe()

    def displayMainWindowBox(self):

        maingrahpic = QVBoxLayout()

        topgraphicBox = qformlayout()
        circle1 = circle.circle()
        topgraphicBox.addWidget(circle1)

        BottomGraphicBox = qformlayout()
        circle2 = circle.circle()
        BottomGraphicBox.addWidget(circle2)

        maingrahpic.addLayout(topgraphicBox)
        maingrahpic.addLayout(BottomGraphicBox)

        return (maingrahpic)

    def initMe(self):

        # define Boxes for BoxLayout
        horizontalmainBox = QHBoxLayout()

        rbtnrow = QVBoxLayout()
        rlabelrow = QVBoxLayout()

        lbtnrow = QVBoxLayout()
        llabelrow = QVBoxLayout()

        bottombtnrow = QHBoxLayout()
        bottomlabelrow = QHBoxLayout()

        maingraphicBox = self.displayMainWindowBox()

        middleBox = QHBoxLayout()
        middleBox.addLayout(llabelrow)
        middleBox.addLayout(maingraphicBox)
        middleBox.addLayout(rlabelrow)

        mainmiddleBox = QVBoxLayout()
        displayvBox = QVBoxLayout()

        frame = qframe()
        frame.setFrameShape(qframe.StyledPanel)
        frame.setStyleSheet("background-color: blue")
        frame.setlinewidth(3)

        displayvBox.addWidget(frame)
        displayvBox.addLayout(middleBox)
        displayvBox.addLayout(bottomlabelrow)

        mainmiddleBox.addLayout(displayvBox)
        mainmiddleBox.addLayout(bottombtnrow)

        horizontalmainBox.addLayout(lbtnrow)
        horizontalmainBox.addLayout(mainmiddleBox)
        horizontalmainBox.addLayout(rbtnrow)

        topBox = QHBoxLayout()
        toprightside = QHBoxLayout()
        toprightside.addStretch(1)
        topleftside = QVBoxLayout()
        topBox.addLayout(toprightside)
        topBox.addLayout(topleftside)

        finalBox = QVBoxLayout()

        finalBox.addLayout(topBox)
        finalBox.addLayout(horizontalmainBox)


        self.setLayout(finalBox)

        self.setGeometry(self.top,self.left,self.width,self.height)
        self.setwindowTitle("ACDI Simulator")
        self.show()

        self.setStyleSheet("background : black;")


app = QApplication(sys.argv)
app.setStyle("fuison")
w = fenster()
sys.exit(app.exec_())

为了使程序代码工作,你需要 circle.py

from PyQt5.QtWidgets import *
from PyQt5 import QtCore,QtGui
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys


class circle(QMainWindow):

    def __init__(self):
        super().__init__()

        timer = QTimer(self)

        timer.timeout.connect(self.update)

        timer.start(500)

        self.setwindowTitle('Circle')

        self.setGeometry(200,200,300,300)

        self.setStyleSheet("background : black;")

        self.rPointer = QtGui.Qpolygon([QPoint(0,0),QPoint(-10,-90),QPoint(10,-90)])

        self.sPointer = QtGui.Qpolygon([QPoint(0,-90)])

        self.bColor = Qt.white

        self.GreenCol = Qt.green

        self.sColor = Qt.red

        self.tik = 0

    def paintEvent(self,event):

        rec = min(self.width(),self.height())

        self.tik = self.tik + 1
        self.tik = self.tik % 360

        painter = QPainter(self)

        def drawPointer(color,rotation,pointer):

            painter.setBrush(QBrush(color))

            painter.save()

            painter.rotate(rotation)

            painter.drawConvexpolygon(pointer)

            painter.restore()

        painter.setRenderHint(QPainter.Antialiasing)

        painter.translate(self.width() / 2,self.height() / 2)

        painter.scale(rec / 200,rec / 200)

        painter.setPen(QtCore.Qt.nopen)

        drawPointer(self.GreenCol,(self.tik),self.rPointer)

        drawPointer(self.sColor,90,self.sPointer)

        painter.setPen(QPen(self.bColor,1,Qt.solidLine))

        painter.setBrush(QBrush(QtCore.Qt.NoBrush))

        painter.drawEllipse(-92,-92,184,184)

        for i in range(0,90):

            if (i % 5) == 0:
                painter.drawLine(87,97,0)

            painter.rotate(9)

        painter.end()


if __name__ == '__main__':

    app = QApplication(sys.argv)

    win = circle()
    win.show()

    sys.exit(app.exec_())

因为我显然无法说出我想要的图片

Since i am clearly not able to tell what i want here a picture

我想要一个围绕 displayvBox 的框架。 displayvBox 包含一些标签和两个圆圈。怎么可能制作这个框架。我真的不明白这个......

解决方法

QFrame 是一个容器小部件,它是一个小部件,仅用于“分组”其他小部件。

如果您想在框架内显示小部件,您不能只将框架添加到布局将这些小部件添加到相同的布局:您需要为框架设置布局,添加小部件到那个布局,然后将框架添加到“主”布局。

在您的情况下,您可以在 DisplayMainWindowBox 中创建框架并直接返回它而不是布局:

    def DisplayMainWindowBox(self):

        frame = QFrame()
        frame.setFrameShape(QFrame.StyledPanel)
        frame.setStyleSheet("background-color: blue")
        frame.setLineWidth(3)

        # directly install the layout on the frame
        maingrahpic = QVBoxLayout(frame)
        # which is the shorthand version of: 
        # maingrahpic = QVBoxLayout(frame)
        # frame.setLayout(maingrahpic)

        topgraphicbox = QFormLayout()
        circle1 = circle()
        topgraphicbox.addWidget(circle1)

        BottomGraphicBox = QFormLayout()
        circle2 = circle()
        BottomGraphicBox.addWidget(circle2)

        maingrahpic.addLayout(topgraphicbox)
        maingrahpic.addLayout(BottomGraphicBox)

        # return the frame,not the layout
        return frame

    def initMe(self):
        # ...
        maingraphicbox = self.DisplayMainWindowBox()

        middlebox = QHBoxLayout()
        middlebox.addLayout(llabelrow)
        middlebox.addWidget(maingraphicbox)
        middlebox.addLayout(rlabelrow)
        # ...

我建议你阅读更多关于 layout management 的内容,并通过 using them in Qt designer 做一些实验,以便你更好地理解 Qt 下的布局管理是如何工作的。
还要考虑到 width()height() 是所有 QWidget 类的现有属性,因此您不应使用自定义变量覆盖它们,因为这样做会使访问这些属性变得更加困难。

最后,您的 circle 子类可能应该继承自 QWidget 而不是 QMainWindow(它通常用作顶级窗口,而不是用作要添加到父级的自定义小部件)。