问题描述
我现在被困了 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_())
因为我显然无法说出我想要的图片:
我想要一个围绕 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(它通常用作顶级窗口,而不是用作要添加到父级的自定义小部件)。