2015-11-22 6 views
1

Я создаю собственный класс qtreewidget, который выполняет автоматическое автоопределение своего окна, чтобы точно соответствовать видимым в данный момент элементам (я не хочу прокручивать). Для этого я запускаю функцию count, чтобы найти количество открытых qtreewidgetitems и их детей и установить фиксированную высоту оттуда. Однако, когда я разворачиваю дочерний виджет (щелкните стрелку разворота на одном из моих элементов), весь вид внезапно нуждается в прокрутке, потому что в нижней части есть лишнее свободное пространство, несмотря на то, что моя функция подсчета точно вычисляет необходимую высоту. Как я могу избавиться от него?qtreewidget нежелательное пустое пространство (дополнительные неустранимые строки)

Ниже приведен рабочий класс, который можно запускать прямо как есть.

import sys 
from PyQt4 import QtGui 
from PyQt4.QtCore import * 
from PyQt4.QtGui import * 


class TreeWidget(QTreeWidget): 
    def __init__(self, parent=None): 
     super(TreeWidget, self).__init__() 
     self.installEventFilter(self) 
     self.setStyleSheet(''' 
      background: None; 
      border: None; 
      outline: None; 
      outline-width: 0px; 
      selection-background-color: blue; 
      ''') 
     header = QtGui.QTreeWidgetItem(["Tree", "First"]) 
     self.setAutoScroll(False) 
     self.setHeaderItem(header) 
     self.header().close() 
     # self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) 

    def fill_item(self, item, value): 
     item.setExpanded(False) 
     if type(value) is dict: 
      for key, val in sorted(value.iteritems()): 
       child = QTreeWidgetItem() 
       child.setText(0, unicode(key)) 
       # child.doubleClicked.connect(lambda: self.doubleClicked1(child)) 
       item.addChild(child) 
       self.fill_item(child, val) 
     elif type(value) is list: 
      last = None 
      for val in value: 
       child = QTreeWidgetItem() 
       if type(val) is dict: 
        item.addChild(child) 
        child.setText(0, '[dict]') 
        # child.doubleClicked.connect(lambda: self.doubleClicked1(child)) 
        self.fill_item(child, val) 
        last = child 
       elif type(val) is list: 
        self.fill_item(last, val) 
       else: 
        item.addChild(child) 
        child.setText(0, unicode(val)) 
        child.setText(1, 'test') 
        # child.doubleClicked.connect(lambda: self.doubleClicked1(child)) 
        child.setExpanded(False) 
        last = child 
     else: 
      child = QTreeWidgetItem() 
      child.setText(0, unicode(val)) 
      child.setText(1, 'test') 
      # child.doubleClicked.connect(lambda: self.doubleClicked1(child)) 
      item.addChild(child) 

    def fill_widget(self, value): 
     self.clear() 
     self.fill_item(self.invisibleRootItem(), value) 

    def resizeEvent(self, event): 
     self.resize() 

    def resize(self): 
     width = 50 
     self.header().resizeSection(1, width) 
     self.header().resizeSection(0, self.width()-width) 
     height = self.visibleCount() 
     print height/15 
     self.setFixedHeight(height+0) 

    def eventFilter(self, source, event): 
     if source is self: 
      if event.type() == 1: 
       self.resize() 
      elif event.type() == QEvent.Leave: 
       self.clearSelection() 
     return QtGui.QTreeWidget.eventFilter(self, source, event) 

    def visibleCount(self, parent=0): 
     height = 0 
     if parent == 0: 
      topHeight = 0 
      for a in xrange(self.topLevelItemCount()): 
       item = self.topLevelItem(a) 
       topHeight += self.visualItemRect(item).height() 
       if item.isExpanded(): 
        height += self.visibleCount(item) 
      height += topHeight 
     else: 
      childHeight = 0 
      for a in xrange(parent.childCount()): 
       item = parent.child(a) 
       childHeight += self.visualItemRect(item).height() 
       if item.isExpanded(): 
        height += self.visibleCount(item) 
      height += childHeight 
     return height 

    def editClicked(self, parent=0): 
     # print 'edit 2' 
     if parent == 0: 
      for a in xrange(self.topLevelItemCount()): 
       item = self.topLevelItem(a) 
       print type(item) 
       item.setExpanded(True) 
       self.editClicked(item) 
     else: 
      for a in xrange(parent.childCount()): 
       item = parent.child(a) 
       print type(item) 
       item.setText(1, '+') 
       item.setExpanded(True) 
       self.editClicked(item) 

    def doubleClicked1(self, widget): 
     print widget 


def main(): 
    app = QtGui.QApplication(sys.argv) 
    ex = TreeWidget() 
    data = [ 
     'Make sure ZMQ remote button gets honored', 
     'Fill in plot', 
     'Remove cycle', 
     'Remove current control or make it working', 
     'Handle possible startup errors with dialogs', 
     'Get improved current read-out (requires hardware changes)', 
     ['1','2','3'], 
     'Email quench notification' 
     ] 
    ex.fill_widget(data) 
    ex.show() 
    sys.exit(app.exec_()) 

if __name__ == '__main__': 
    main() 

ответ

1

Вы можете удалить фильтр событий целиком. Вы должны изменить размер виджета, когда элементы будут развернуты или свернуты. Оба действия запускают сигналы, поэтому вы можете просто подключить эти сигналы к resize:

class TreeWidget(QTreeWidget): 
    def __init__(self, parent=None): 
     super(TreeWidget, self).__init__(parent) 
     self.expanded.connect(self.resize) 
     self.collapsed.connect(self.resize) 
+0

Это сделало это. Обратите внимание, что фильтр событий по-прежнему необходим для захвата события leave для очистки любого текущего выбора. –