用于 BoxLayout 的 PyQt 框架

PyQt Frame for BoxLayout

我现在已经被困了 2 个多小时,试图在我的 Boxlayout 周围放置一个 frame/border。

这是主要的最小化 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, 0),
                                        QPoint(-10, -90),
                                        QPoint(10, -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, 0, 97, 0)

            painter.rotate(9)

        painter.end()


if __name__ == '__main__':

    app = QApplication(sys.argv)

    win = circle()
    win.show()

    sys.exit(app.exec_())

因为我显然不能在这里说出我想要的图片:

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

QFrame 是一个容器小部件,它是一种仅用作“分组”其他小部件的方式的小部件。

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

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

    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 and also do some experimenting by using them in Qt designer 的内容,以便您更好地理解布局管理在 Qt 下的工作方式。
还要考虑 width() and height() 是所有 QWidget 类 的现有属性,因此您不应使用自定义变量覆盖它们,因为这样做会使访问这些属性更加困难。

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