2015-05-18 9 views
1

Так что я новичок в QtGui и смотрю, как делать вещи, и я нашел это аккуратным example on QTreeView. Когда я получил это работает самостоятельно, я заметил, что он не заполняет пространство, как я ожидал:QTreeView не покрывает родительскую ширину или высоту

enter image description here

Так что я искал ответы, и не находя много ни Python или Ресурсы C++. Я был checking the documentation много, но все еще не совсем нашел то, что искал.

Так что кажется ясным, что в чем-то нет правильной политики размера, но мне сложно понять, что. Я до сих пор устранено несколько потенциальных кандидатов:

  • Экземпляр QWidget держит экземпляр QTreeView правильно охватывает макет он находится в (QWidget охватывает ширину QGroupBox минус немного на полях).
  • Поскольку родительский виджет QTreeView - это правильные размеры, я понял, что это нечто более локальное для QTreeView, но когда я использую setSizePolicy, ни одна из используемых мной политик, похоже, не устраняет проблему. Возможно, несколько шагов, о которых я не знаю?
  • QTreeView унаследовал viewport (от QAbstractScrollArea гораздо меньше, чем я ожидал. Вызов setViewport() метод QTreeView с новым и пустой QWidget только перерисовывает содержимое фона без заголовка в серый цвет, а не белый, и я подозреваю, что это близко, но не где нужно искать.
  • QTreeView есть другие дети (помимо viewport), что я до сих пор исследования.
  • Большинство из того, что я пытался, я оставил комментарий в моем коде ниже.

Это мой исходный код для воспроизведения:

import sys 
from PySide.QtGui import * 


class TreeTime(QMainWindow): 
    def __init__(self): 
     super().__init__() 
     self.initUI() 

    def initUI(self): 
     self.main_widget = QWidget() 
     self.main_layout = QVBoxLayout() 
     self.main_widget.setLayout(self.main_layout) 
     self.setCentralWidget(self.main_widget) 
     self.statusBar() 

     self.make_tree() 

     self.show() 

    def make_tree(self): 
     # init widgets 
     self.tgb = QGroupBox("[Tree Group Box Title]") 
     self.main_layout.addWidget(self.tgb) 

     tgb_layout = QVBoxLayout() 
     self.tgb.setLayout(tgb_layout) 

     tgb_widget = QWidget() 
     tgb_layout.addWidget(tgb_widget) 

     debug_btn = QPushButton("DEBUG") 
     tgb_layout.addWidget(debug_btn) 

     view = QTreeView(parent=tgb_widget) 
     # view.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) 
     view.setSelectionBehavior(QAbstractItemView.SelectRows) 
     model = QStandardItemModel() 
     model.setHorizontalHeaderLabels(['col1', 'col2', 'col3']) 
     view.setModel(model) 
     view.setUniformRowHeights(True) 

     # populate data 
     for i in range(10): 
      parent1 = QStandardItem('Family {}. Some long status text for sp'.format(i)) 
      for j in range(3): 
       child1 = QStandardItem('Child {}'.format(i*3+j)) 
       child2 = QStandardItem('row: {}, col: {}'.format(i, j+1)) 
       child3 = QStandardItem('row: {}, col: {}'.format(i, j+2)) 
       parent1.appendRow([child1, child2, child3]) 
      model.appendRow(parent1) 
      # span container columns 
      view.setFirstColumnSpanned(i, view.rootIndex(), True) 

     # expand third container 
     index = model.indexFromItem(parent1) 
     view.expand(index) 

     # select last row 
     selmod = view.selectionModel() 
     index2 = model.indexFromItem(child3) 
     selmod.select(index2, QItemSelectionModel.Select|QItemSelectionModel.Rows) 

     def print_debug_info(): 
      print('') 
      for child in view.children(): 
       print("child "+repr(child)) #not sure what all these are yet 
      print('') 
      print('self.main_widget.frameSize: '+repr(self.main_widget.frameSize())) 
      print('view.parent().parent().frameSize(): '+repr(view.parent().parent().frameSize())) #group box 
      # print('self.frameSize: '+repr(self.frameSize())) 
      print('self.tgb.frameSize: '+repr(self.tgb.frameSize())) 
      print('view.parent(): '+repr(view.parent())) 
      print('view.parent().frameSize(): '+repr(view.parent().frameSize())) 
      # print('view.parent().frameSize(): '+repr(view.parent().frameSize())+" (before)") 
      # print('view.parent().adjustSize(): '+repr(view.parent().adjustSize())) 
      # print('view.parent().frameSize(): '+repr(view.parent().frameSize())+" (after)") 
      print('view.viewport(): '+repr(view.viewport())) 
      print('view.viewport().frameSize(): '+repr(view.viewport().frameSize())) 
      # print('view.parent().parent().parent().frameSize(): '+repr(view.parent().parent().parent().frameSize())) 
      # print('calling setViewport: '+repr(view.setViewport(QWidget()))) 
      # view.adjustSize() 

     debug_btn.clicked.connect(print_debug_info) 

    def sayHello(self): 
     self.statusBar().showMessage("Hello World!") 
     import time; time.sleep(2) 
     self.statusBar().showMessage("") 

    def sayWords(self, words): 
     self.statusBar().showMessage(words) 


if __name__ == '__main__': 
    app = QApplication([]) 
    tt = TreeTime() 
    sys.exit(app.exec_()) 

Я использую машину Windows 8.1 и Python 3.4.3, PySide версии 1.2.2 - любая помощь будет высоко оценена! (Также, пожалуйста, дайте мне знать, если я оставил любые важные детали)

UPDATE (5/19/2015): Я пытался двигаться мою кнопку DEBUG вне QGroupBox, и результат был тот QTreeView разваливались в полностью nonlegible размер, так что вы не могли бы даже сказать, что объект был больше, так что, похоже, сводя к минимуму использование пространства, даже когда я раскомментировать строку:

view.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

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

UPDATE 5/19/2015: Я реализовал совет, предоставленный @titusjan, но у меня такая же проблема/поведение.

ответ

1

Вы должны удалить избыточную tp_widget и добавить view к tgb_layout:

def make_tree(self): 
    # init widgets 
    self.tgb = QGroupBox("[Tree Group Box Title]") 
    self.main_layout.addWidget(self.tgb) 

    tgb_layout = QVBoxLayout() 
    self.tgb.setLayout(tgb_layout) 

    view = QTreeView() 
    tgb_layout.addWidget(view) 

    ... 

    debug_btn = QPushButton("DEBUG") 
    tgb_layout.addWidget(debug_btn) 

Обратите внимание, что при добавлении виджетов в макет, они будут автоматически повторно родительским родителю макета (всякий раз, когда это получает один), поэтому на самом деле не нужно устанавливать его в конструкторе.

Также обратите внимание, что это:

tgb_layout = QVBoxLayout(self.tgb) 

в точности эквивалентно следующему:

tgb_layout = QVBoxLayout() 
    self.tgb.setLayout(tgb_layout) 

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

+0

Aha! Я вижу - я почему-то думал, что должен добавить QTreeView в QWidget, а затем добавить этот QWidget в представление. Я не уверен, как я застрял в голове. Большое спасибо за то, что помогли мне справиться с этим! Теперь я работаю. – LastTigerEyes

1

Чтобы связать макет с виджетами, необходимо использовать метод setLayout. Так что измените ...

self.main_layout = QVBoxLayout(self.main_widget) 

в

self.main_layout = QVBoxLayout() 
self.main_widget.setLayout(self.main_layout) 

Похожие на tgb_view макете (который я бы переименовывать в tgb_layout для ясности).

Наконец, вы забыли добавить древовидную к этой схеме, так что добавьте:

tgb_view.addWidget(view) 

Я положил весь соответствующий измененный код ниже для удобства.

def initUI(self): 
    self.main_widget = QWidget() 
    self.main_layout = QVBoxLayout() 
    self.main_widget.setLayout(self.main_layout) 
    self.setCentralWidget(self.main_widget) 
    self.statusBar() 
    self.make_tree() 

    self.show() 

def make_tree(self): 
    # init widgets 
    self.tgb = QGroupBox("[Tree Group Box Title]") 
    self.main_layout.addWidget(self.tgb) 

    tgb_view = QVBoxLayout() 
    self.tgb.setLayout(tgb_view) 
    tgb_widget = QWidget() 
    tgb_view.addWidget(tgb_widget) 

    debug_btn = QPushButton("DEBUG") 
    tgb_view.addWidget(debug_btn) 

    view = QTreeView(parent=tgb_widget) 
    tgb_view.addWidget(view) 
    ... 

Сведения о политике в отношении размера не нужны, значения по умолчанию прекрасны.

+0

Интересно! У меня создалось впечатление, что макет с родительским виджетами, переданный ему при построении, будет назначен как макет этого виджета. Я выполнил ваши рекомендации @titusjan, но у меня такое же поведение ... Я редактирую свое оригинальное сообщение, чтобы отразить изменения, внесенные в код. – LastTigerEyes

+0

@LastTigerEyes. Ваше впечатление было совершенно правильным. – ekhumoro

+0

@LastTigerEyes: это потому, что вы не добавили строку 'tgb_view.addWidget (view)'. – titusjan