首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Qt图形框架中等效的DIV标记

Qt图形框架中等效的DIV标记
EN

Stack Overflow用户
提问于 2015-04-19 17:58:08
回答 1查看 1.1K关注 0票数 0

我正在开发一个简单的桌面应用程序,在这个应用程序中,我必须显示文件夹和文件的树状结构以及其他图表。为此,我选择了Qt和python (PySide)。我需要像下面这样的结构(请原谅我画得不好)。但你知道):

可以双击文件夹以展开/缩小文件夹。当文件夹展开时,新的子元素需要占用更多的空间,并且当前文件夹下的文件夹必须向下移动。类似地,当文件夹缩小时,当前文件夹下面的文件夹必须出现;就像标准文件夹系统一样。

因此,我在Qt中寻找一个<div>等效元素,在该元素中,可以将每个目录及其所有子目录放置在该div中,div可以展开和缩小。这样,每次打开/关闭文件夹时,我都不必为重新绘制编写代码。目前,我必须计算每个项目的位置,并将子项分别放置到该位置。这是一个很大的计算,而没有一个项目是> 1000。With a div, I will just re-calculate positions of child items and resize the div. Other divs can then automatically re-draw themselves.

我不使用QTreeView,因为正如我前面所说,我必须绘制其他图表并将这些文件夹与它们连接起来。QTreeView将生活在自己的空间中(有滚动条和其他东西),我将无法绘制线来连接QTreeView和QGraphicsScene中的项目。

您可以在github中查看我当前的工作这里这是我工作的文件。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-20 14:43:58

我不知道你在想什么"<div>“。它只是最简单的HTML容器,它似乎与您的目标无关。

您可以使用图形布局来自动对齐场景中的项目。以下是如何实现它:

代码语言:javascript
复制
from PySide import QtGui, QtCore

class Leaf(QtGui.QGraphicsProxyWidget):
  def __init__(self, path, folder = None):
    QtGui.QGraphicsProxyWidget.__init__(self)
    self.folder = folder
    label = QtGui.QLabel()
    label.setText(QtCore.QFileInfo(path).fileName())
    self.setWidget(label)
    self.setToolTip(path)
    self.setAcceptedMouseButtons(QtCore.Qt.LeftButton)

  def mousePressEvent(self, event):
    if self.folder:
      self.folder.toggleChildren()

class Folder(QtGui.QGraphicsWidget):
  def __init__(self, path, isTopLevel = False):
    QtGui.QGraphicsWidget.__init__(self)
    self.offset = 32
    childrenLayout = QtGui.QGraphicsLinearLayout(QtCore.Qt.Vertical)
    childrenLayout.setContentsMargins(self.offset, 0, 0, 0)

    flags = QtCore.QDir.AllEntries | QtCore.QDir.NoDotAndDotDot
    for info in QtCore.QDir(path).entryInfoList(flags):
      if info.isDir():
        childrenLayout.addItem(Folder(info.filePath()))
      else:
        childrenLayout.addItem(Leaf(info.filePath()))

    self.childrenWidget = QtGui.QGraphicsWidget()
    self.childrenWidget.setLayout(childrenLayout)

    mainLayout = QtGui.QGraphicsLinearLayout(QtCore.Qt.Vertical)
    mainLayout.setContentsMargins(0, 0, 0, 0)
    self.leaf = Leaf(path, self)
    mainLayout.addItem(self.leaf)
    mainLayout.addItem(self.childrenWidget)
    if isTopLevel:
      mainLayout.addStretch()
    self.setLayout(mainLayout)

  def paint(self, painter, option, widget):
    QtGui.QGraphicsWidget.paint(self, painter, option, widget)
    if self.childrenWidget.isVisible() and self.childrenWidget.layout().count() > 0:
      lastChild = self.childrenWidget.layout().itemAt(self.childrenWidget.layout().count() - 1)
      lastChildY = self.childrenWidget.geometry().top() + \
          lastChild.geometry().top() + self.leaf.geometry().height() / 2;
      painter.drawLine(self.offset / 2, self.leaf.geometry().bottom(), self.offset / 2, lastChildY)
      for i in range(0, self.childrenWidget.layout().count()):
        child = self.childrenWidget.layout().itemAt(i)
        childY = self.childrenWidget.geometry().top() + \
            child.geometry().top() + self.leaf.geometry().height() / 2
        painter.drawLine(self.offset / 2, childY, self.offset, childY)

  def toggleChildren(self):
    if self.childrenWidget.isVisible():
      self.layout().removeItem(self.childrenWidget)
      self.childrenWidget.hide()
      self.leaf.widget().setStyleSheet("QLabel { color : blue; }")
      print "hide"
    else:
      self.childrenWidget.show()
      self.layout().insertItem(1, self.childrenWidget)
      self.leaf.widget().setStyleSheet("")
    self.update()

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    scene = QtGui.QGraphicsScene()
    view = QtGui.QGraphicsView(scene)
    # put your root path here
    scene.addItem(Folder("/usr/share/alsa", True))
    view.show()
    view.resize(400, 400)
    sys.exit(app.exec_())

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29733649

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档