我正在尝试创建一个简单的gui来显示设备的某些组件的(内存)布局,但是我很难执行我想要的策略到显示区域。
让我首先展示一下到目前为止的情况(我的代码变得相当大,但我将代码更改/缩小到任何人都能运行它所需的最低限度):
#!/usr/local/bin/python3
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
class Register(QGraphicsRectItem):
RegisterSize = 125
NameColor = QColor(Qt.blue)
ValueColor = QColor(0, 154, 205)
def __init__(self, name, value, pos, parent = None):
super(Register, self).__init__(parent)
self.setPos(pos)
self.width = Register.RegisterSize
self.height = 0
self.set_register_name(name)
self.set_register_value(value)
self.setRect(0, 0, self.width, self.height)
def set_register_name(self, name):
self.text_item = QGraphicsTextItem(name, self)
self.text_item.setDefaultTextColor(Register.NameColor)
self.height += self.text_item.boundingRect().height()
def set_register_value(self, value):
self.value_item = QGraphicsTextItem(str(value), self)
self.value_item.setDefaultTextColor(Register.ValueColor)
self.value_item.setPos(self.text_item.boundingRect().bottomLeft())
self.height += self.value_item.boundingRect().height()
class Title(QGraphicsTextItem):
TitleFont = 'Times New Roman'
TitleFontSize = 18
TitleColor = QColor(Qt.red)
def __init__(self, title, parent = None):
super(Title, self).__init__(title, parent)
self.setFont(QFont(Title.TitleFont, Title.TitleFontSize))
self.setDefaultTextColor(Title.TitleColor)
class Component(QGraphicsItem):
def __init__(self, parent = None):
super(Component, self).__init__(parent)
self.width = Register.RegisterSize * 4
self.height = 0
self.add_title()
self.add_registers()
self.rect = QRectF(0, 0, self.width, self.height)
def add_title(self):
self.title = Title('Component Layout', self)
self.title.setPos((self.width - self.title.boundingRect().width()) / 2, 0)
self.height += self.title.boundingRect().height()
def add_registers(self):
y_coor = self.height
x_coor = 0
for i in range(64):
register = Register('register {0:d}'.format(i), i, QPointF(x_coor, y_coor), self)
x_coor = ((i + 1) % 4) * Register.RegisterSize
if (i + 1) % 4 == 0:
y_coor += register.rect().height()
self.height = y_coor
def boundingRect(self):
return self.rect.adjusted(-1, -1, 1, 1)
def paint(self, painter, option, widget):
pen = QPen(Qt.blue)
painter.setPen(pen)
painter.drawRect(self.rect)
class Device(QGraphicsItem):
LeftMargin = 50
RightMargin = 50
TopMargin = 20
BottomMargin = 20
def __init__(self, parent = None):
super(Device, self).__init__(parent)
self.width = Device.LeftMargin + Device.RightMargin
self.height = Device.TopMargin + Device.BottomMargin
component = Component(self)
component.setPos(QPointF(Device.LeftMargin, Device.TopMargin))
self.width += component.boundingRect().width()
self.height += component.boundingRect().height()
self.rect = QRectF(0, 0, self.width, self.height)
def paint(self, painter, option, widget):
pass
def boundingRect(self):
return self.rect.adjusted(-1, -1, 1, 1)
class MainForm(QDialog):
def __init__(self, parent = None):
super(MainForm, self).__init__(parent)
self.scene = QGraphicsScene(parent)
self.view = QGraphicsView(self)
self.view.setScene(self.scene)
self.scene.addItem(Device())
self.resize(700, 900)
def run_app():
app = QApplication(sys.argv)
form = MainForm()
form.show()
app.exec_()
if __name__ == '__main__':
run_app()
当启动此代码时,将显示以下内容:
我不介意垂直滚动条,因为我打算向设备中添加更多组件,而且它们都不适合,困扰我的是水平滚动条。
为什么在我没有明确询问的情况下就出现了?
这并不是说QGraphicsView
窗口中没有显示内容的空间。
此外,我注意到水平(和垂直)滚动条没有出现,当只有组件被添加到时,QGraphicsView
:
self.scene.addItem(Component()) # << previously was self.scene.addItem(Device())
现在不出现滚动条:
另外,当我更改以下行时:
LeftMargin = 0 # previously was 50
RightMargin = 0 # previously was 50
TopMargin = 0 # previously was 20
BottomMargin = 0 # previously was 20
滚动条不出现。(我可能越过了一些边界,加上了这些边距?)
我知道我可以使用QGraphicsView.setHorizontalScrollBarPolicy()
控制滚动条策略,使水平滚动条始终关闭,但这带来了另一个问题:当无法向右滚动时,垂直滚动条将从显示中“窃取”一些像素,从而生成Device.RightMargin != Device.LeftMargin
。另外,我很好奇水平/垂直滚动条出现的大小边界是什么。
因此,这是我要执行的政策:
Device()
的高度如何),而垂直滚动条只有在的高度通过这些X像素边界(我将通过所有Component()
的高度之和确定Device()
的高度)时才会显示为。Device()
的宽度是固定的,并且与Component()
s的数量无关)。编辑
玩了一会儿之后,我想了想:
Qt::ScrollBarAsNeeded
,这意味着:“当内容太大时显示滚动条,而不是其他内容。”但它没有说明什么被认为“太大”。
当我玩边距(Device.TopMargin
/Device.BottomMargin
)时,我发现当Device.boundingRect().height()
越过786像素边界时,垂直滚动条就会出现(因此也会出现水平滚动条)。
我不知道这个号码是从哪里来的,也不知道怎么控制它。发布于 2017-09-22 12:46:22
我相信你在找setFixedWidth()
和setFixedHeight()
class MainForm(QDialog):
def __init__(self, parent = None):
super(MainForm, self).__init__(parent)
self.scene = QGraphicsScene(parent)
self.view = QGraphicsView(self)
self.view.setScene(self.scene)
self.scene.addItem(Device())
self.resize(700, 900)
self.view.setFixedWidth(650) # <-
self.view.setFixedHeight(500) # <- these two lines will set Device dimensions
self.setFixedWidth(700) # <- this will fix window width
当您将固定宽度设置为view
时,它必须大于其内容(左边距+ Device
+右边距),否则将显示水平滚动条。这就是为什么在边距为零时没有得到水平滚动条的原因。
通常,当当前视图无法显示内容时,滚动条将出现。
垂直滚动条将占用一些空间,从窗口,我相信你没有控制,所以你应该为它预留一些地方,也。垂直滚动条的行为取决于您的windows系统,例如,在Mac上,它在不需要的情况下盘旋并消失,因此它根本不占用空间。
我建议在QT设计器中进行布局。我发现直观地做它要容易得多,立即对它进行测试,并且只在生成的代码中引入一些小的更改。
https://stackoverflow.com/questions/46246196
复制相似问题