2012-03-12 6 views
2

У меня есть QtreeView как вид в QComboBox. В моем приложении корневые элементы являются метками категории и не должны быть выбраны. Когда я создаю представление, я хотел бы предварительно выбрать один из дочерних элементов (первый корневой элемент выбран по умолчанию), но я не могу понять, как это сделать. Примерами этого являются (особенно для питона), тонкие на земле.Как выбрать элемент в QTreeView, который находится внутри QComboBox

Вот мой упрощенный пример:

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

data = [ (("Cat A",False), [(("Thing 1",True), []),(("Thing 2",True), [])]), 
    (("Cat B",False), [(("Thing 3",True), []), (("Thing 4",True), [])])] 

class MyComboBox(QComboBox): 
    def __init__(self): 
     super(QComboBox,self).__init__() 
     self.setView(QTreeView()) 

     self.view().setHeaderHidden(True) 
     self.view().setItemsExpandable(False) 
     self.view().setRootIsDecorated(False) 

    def showPopup(self): 
     self.view().expandAll() 
     QComboBox.showPopup(self) 

class Window(QWidget): 
    def __init__(self): 

     QWidget.__init__(self) 

     self.model = QStandardItemModel() 
     self.addItems(self.model, data) 

     self.combo = MyComboBox() 
     self.combo.setModel(self.model) 

     layout = QVBoxLayout() 
     layout.addWidget(self.combo) 
     self.setLayout(layout) 

     # I can choose which combobox item to select here, but I am unable to 
     #choose child items 
     #self.combo.setCurrentIndex(1) 

    def addItems(self, parent, elements): 
     for text, children in elements: 
      item = QStandardItem(text[0]) 
      # root items are not selectable, users pick from child items 
      item.setSelectable(text[1]) 
      parent.appendRow(item) 
      if children: 
       self.addItems(item, children) 

if __name__ == "__main__": 
    app = QApplication(sys.argv) 
    window = Window() 
    window.show() 
    sys.exit(app.exec_()) 

Я работал из примеров here и here

вопрос в значительной степени был задан before, но не для питона, и решение разместило Безразлично Я работаю для меня.

ответ

2

Это альтернативный и более общий способ для вашего текущего кода. Он будет работать для дополнительного уровня вложенных элементов и любой конфигурации выбираемых элементов.

class MyComboBox(QComboBox): 
    def __init__(self): 
     super(MyComboBox,self).__init__() # your super was wrong. 
              # you need to pass the _current_ class name 
     self.setView(QTreeView()) 

     self.view().setHeaderHidden(True) 
     self.view().setItemsExpandable(False) 
     self.view().setRootIsDecorated(False) 

    def showPopup(self): 
     self.setRootModelIndex(QModelIndex()) # you need to add this 
     self.view().expandAll() 
     QComboBox.showPopup(self) 

    def setModel(self, model): 
     super(MyComboBox, self).setModel(model) 
     parent, row = self._firstSelectableItem() 
     if row is not None: 
      self.setRootModelIndex(parent) 
      self.setCurrentIndex(row) 

    def _firstSelectableItem(self, parent=QModelIndex()): 
     """ 
     Internal recursive function for finding the first selectable item. 
     """ 
     for i in range(self.model().rowCount(parent)): 
      itemIndex = self.model().index(i,0,parent) 
      if self.model().itemFromIndex(itemIndex).isSelectable(): 
       return parent, i 
      else: 
       itemIndex, row = self._firstSelectableItem(itemIndex) 
       if row is not None: 
        return itemIndex, row 
     return parent, None 
+0

thats отлично, подходит мне лучше. спасибо (оба) за то, что нашли время! (спасибо за супер примечание тоже) – tom

0

Это будет работать, если вы используете QTreeWidget и как мнение и модели на вашем комбобоксе т.е.

self.tree = QTreeWidget() 
self.combo.setModel(self.tree.model()) 
self.combo.setView(self.tree) 

Кроме того, вы должны изменить ваши AddItems() функцию, чтобы построить QTreeWidget с QTreeWidgetItem-х годов, как дети и магазин родительский элемент дочернего элемента, который вы хотите выбрать (PARENTOFITEMSELECTED). После того, как вы сделали это, следующий будет выбрать пункт в вашем treewidget:

self.tree.setCurrentItem(PARENTOFITEMSELECTED, 0) 
self.combo.setRootModelIndex(self.tree.currentIndex()) 
self.combo.setCurrentIndex(CHILDITEMINDEX) 
self.tree.setCurrentItem(self.tree.invisibleRootItem(), 0) 
self.combo.setRootModelIndex(self.tree.currentIndex()) 

Это основано на примере найден here.

Надеюсь, это поможет.

+0

Да, это работает для меня - я видел этот пример, но не сделал прыжок в QTreeWidget. Большое спасибо! – tom

 Смежные вопросы

  • Нет связанных вопросов^_^