gpt4 book ai didi

python - PyQt:如何在QGraphicsView中设置滚动条和显示区域大小策略

转载 作者:太空宇宙 更新时间:2023-11-03 15:51:41 24 4
gpt4 key购买 nike

我正在尝试创建一个简单的图形用户界面来显示设备某些组件的(内存)布局,但我很难对显示区域执行我想要的策略。
让我首先展示我目前所拥有的(我的代码变得相当大,但我将代码更改/缩小到任何人都能够运行它所需的最低限度):

#!/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()

此代码在启动时显示以下内容:

enter image description here

我不介意垂直滚动条,因为我打算向设备添加更多组件,但它们并不完全适合,令我困扰的是水平滚动条
为什么没有我明确询问就出现了?
并不是说窗口中没有空间供 QGraphicsView 显示内容。

此外,我注意到水平(和垂直)滚动条不会出现,当仅将组件添加QGraphicsView 时:

self.scene.addItem(Component()) # << previously was self.scene.addItem(Device())

现在滚动条不出现了:
enter image description here

还有;当我改为更改以下行时:

LeftMargin = 0  # previously was 50
RightMargin = 0 # previously was 50

TopMargin = 0 # previously was 20
BottomMargin = 0 # previously was 20

滚动条不出现。 (我可能越过了添加这些边距的边界?)
我知道我可以使用 QGraphicsView.setHorizo​​ntalScrollBarPolicy() 控制滚动条策略,使水平滚动条始终关闭,但这会引发另一个问题:当无法向右滚动时,垂直滚动条会“窃取”显示器的一些像素,使 Device.RightMargin != Device.LeftMargin。另外,我很好奇水平/垂直滚动条出现的大小边界是多少。

所以,这是我要执行的政策:

  • 我希望显示区域的最小高度始终为 X 像素(无论 Device() 的高度如何),并且只有当Device() 高度通过这些 X 像素边界(我将通过对所有 Component() 求和来确定 Device() 的高度>s 高度)

  • 我希望 QGraphicsView 从不显示水平滚动条(宽度 Device() 的宽度是固定的并且与 Component() 的数量无关) .

  • 每当需要垂直滚动条时,我都不希望它占用我的显示区域的像素。
  • 我想知道滚动条将在其上方出现的边界(以像素为单位)是多少(当我未指定滚动条策略时)。

编辑:
玩了一会儿之后,我想到了一些东西:

  • 不需要的水平滚动条出现只是因为垂直滚动条出现并占用了一些显示空间。

  • 根据 doc , 水平滚动条的默认策略是 Qt::ScrollBarAsNeeded ,这意味着:“当内容太大而不适合时显示滚动条。”,但它没有说明什么被认为是“太大”。
    当我调整边距 (Device.TopMargin/Device.BottomMargin) 时,我发现当 Device.boundingRect().height() 越过 786 像素边界。
    我想不通这个数字是从哪里来的,也不知道如何控制它。

最佳答案

我相信您正在寻找 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+右边距),否则会显示水平滚动条。这就是当边距为零时您没有得到水平滚动条的原因。

一般情况下,当你当前的 View 无法显示内容时,滚动条就会出现。

垂直滚动条会占用窗口内部的一些空间,我相信你无法控制它,所以你也应该为它预留一些空间。垂直滚动条的行为取决于您的 Windows 系统,例如在 Mac 上,它悬停在上方并在不需要时消失,因此它根本不占用空间。

我建议在 QT Designer 中进行布局。我发现直观地进行操作要容易得多,立即对其进行测试并且只在生成的代码中引入小的更改。

关于python - PyQt:如何在QGraphicsView中设置滚动条和显示区域大小策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46246196/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com