poluna |
Дата 16.12.2015, 16:06 |
|
Все, поняла, все работает!
Выкладываю работающий пример, так же на python:
#! /usr/bin/python # -*- coding: UTF-8 -*-
import sys from PyQt4 import QtCore, QtGui
class TreeComboBox(QtGui.QComboBox): def __init__(self, parent=None): super(QtGui.QComboBox, self).__init__(parent) self._skipNextHide = False self._treeView = QtGui.QTreeView(self) self.setView(self._treeView) self._treeView.header().hide() self._treeView.viewport().installEventFilter(self)
def eventFilter( self, object, event): if event.type() == QtCore.QEvent.MouseButtonPress and object == self.view().viewport(): index = self.view().indexAt(event.pos()) if not self.view().visualRect(index).contains(event.pos()): self._skipNextHide = True return False
def showPopup(self): self.setRootModelIndex(QtCore.QModelIndex()) self._treeView.expandAll() QtGui.QComboBox.showPopup(self)
def hidePopup(self): if self._skipNextHide: self._skipNextHide = False else: self.setRootModelIndex(self.view().currentIndex().parent()) self.setCurrentIndex(self.view().currentIndex().row()) QtGui.QComboBox.hidePopup(self)
class Main(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent)
self._comboBox = TreeComboBox(self) self._treeView = QtGui.QTreeView(self)
layout = QtGui.QVBoxLayout() layout.addWidget(self._comboBox) layout.addWidget(self._treeView) self.setLayout(layout)
model = QtGui.QStandardItemModel() for a in range(3): i = QtGui.QStandardItem('Item ' + str(a)) for b in range(3): ii = QtGui.QStandardItem('sub 1 Item ' + str(b)) i.setChild(b, ii) for c in range(3): iii = QtGui.QStandardItem('sub 2 Item ' + str(c)) ii.setChild(c, iii) model.appendRow(i)
self._comboBox.setModel(model) self._treeView.setModel(model)
self.connect(self._treeView, QtCore.SIGNAL("clicked(const QModelIndex&)"), self.comboSelect)
def comboSelect(self, idx): self._comboBox.setRootModelIndex(idx.parent()) self._comboBox.setCurrentIndex(idx.row())
if __name__ == "__main__": app = QtGui.QApplication(sys.argv)
main = Main() main.show()
sys.exit(app.exec_())
lanz, спасибо огромное! |
lanz |
Дата 16.12.2015, 14:53 |
|
poluna, ну у меня ваш код вроде работает как надо, ЧЯДНТ? Немножко поменял hidePopup, чтобы он сразу все не корячил:
def hidePopup(self): if self._skipNextHide: self._skipNextHide = False else: self.setRootModelIndex(self.view().currentIndex().parent()) self.setCurrentIndex(self.view().currentIndex().row()) QtGui.QComboBox.hidePopup(self)
|
poluna |
Дата 16.12.2015, 13:34 |
|
lanz, если в комбобоксе стандартными средствами можно показать дерево, то твой метод подойдет, но я не смогла. Как я поняла для показа дерева в комбобокс нужно переопределять класс, я сделала так:
#! /usr/bin/python # -*- coding: UTF-8 -*-
from PyQt4 import QtCore, QtGui
class TreeComboBox(QtGui.QComboBox): def __init__(self, parent=None): super(QtGui.QComboBox, self).__init__(parent) self._skipNextHide = False self._treeView = QtGui.QTreeView(self) self.setView(self._treeView) self._treeView.header().hide() self._treeView.viewport().installEventFilter(self)
def eventFilter( self, object, event): if event.type() == QtCore.QEvent.MouseButtonPress and object == self.view().viewport(): index = self.view().indexAt(event.pos()) if not self.view().visualRect(index).contains(event.pos()): self._skipNextHide = True return False
def showPopup(self): self.setRootModelIndex(QtCore.QModelIndex()) self._treeView.expandAll() QtGui.QComboBox.showPopup(self)
def hidePopup(self): self.setRootModelIndex(self.view().currentIndex().parent()) self.setCurrentIndex(self.view().currentIndex().row()) if self._skipNextHide: self._skipNextHide = False else: QtGui.QComboBox.hidePopup(self) если я не права, то буду только рада, сразу куча проблем исчезнет! Но пока не знаю как! |
ViGOur |
Дата 16.12.2015, 13:27 |
|
А по моему Алексей1153 предложил хороший способ, я сам подобным же пользуюсь. Есть список (QList) или дерево(QMap), которое откуда-то загружается и которое отображается в модели. Очень удобно добавлять, редактировать, удалять. А модель это же абстракция и она не должна по идее хранить данные, как и вид.
lanz, выше сказано
Цитата(poluna @ 15.12.2015, 17:11) Есть у меня класс TreeComboBox, как можно понять из названия в QComboBox у меня находится QTreeView. и как я понимаю твой метод идеально подходит для QComboBox, но не для переопределенного класса. Дождемся автора, что она скажет!
|
Алексей1153 |
Дата 16.12.2015, 13:00 |
|
lanz, да можно и в модели хранить, но я так не люблю делать, это же неудобно ))
lanz, оно, вообще говоря, так и происходит - противоречий нету, но некоторые операции по своему контейнеру удобнее производить
А в данном случае твой вариант лучше будет, конечно ) |
lanz |
Дата 16.12.2015, 12:44 |
|
Цитата "внемодельное" дерево Ойойой, не слушайте его, он вас плохому научит! По идее модель в комбобоксе и модель в дереве слева - это должна быть одна и та же модель. Поэтому индекс от одного должен подходить к индексу от другого.
Т.е. вы сначала получаете выделенный индекс от дерева (назовем его idx)
потом в комбобоксе делаете
combo->setRootModelIndex(idx.parent()) combo->setCurrentIndex(idx.row())
http://doc.qt.io/qt-4.8/qcombobox.html#setRootModelIndex http://doc.qt.io/qt-4.8/qcombobox.html#currentIndex-prop |
poluna |
Дата 16.12.2015, 12:36 |
|
Теперь я поняла тебя. Вариант неплох, и вроде как даже проще в реализации.
Всё, вопрос пока снимаю. Знаю как реализовывать! |
Алексей1153 |
Дата 16.12.2015, 12:28 |
|
poluna, у меня обычно есть "внемодельное" дерево - источник, по которому модель пересобирается. Контейнер обычно на основе QMap<>
struct s_item { s_item* m_parent; QVector<s_item*> m_children;
...
};
s_item* m_root; QMap<s_item*,s_item*> m_tree;
У тебя этой очень удобной детальки , похоже, нету, поэтому мы не и понимаем друг друга В контейнере всё ищется и перебирается запросто |
poluna |
Дата 16.12.2015, 12:10 |
|
И я о том же! Видимо я не так выражаюсь.
На картинке, показано, что у меня есть. В диалоге "Создание группы" указывается, родитель он должен быть выбран таким же, как и выделенный в левом дереве основного окна. А я пока могу выбрать только ветки первого уровня. Так надеюсь понятней, что мне нужно.
Или я тебя не понимаю! |
Алексей1153 |
Дата 16.12.2015, 11:31 |
|
Цитата(poluna @ 16.12.2015, 13:27) Мне просто нужен комбобокс с деревом так он же уже есть, как я понял )) Осталось обработку в дерево добавить |
Просмотр темы полностью (откроется в новом окне) |
|