crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в Получение порядкового номера QTreeView
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
 

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
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, ну у меня ваш код вроде работает как надо, ЧЯДНТ? :lol:
Немножко поменял 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
 
Цитата
"внемодельное" дерево

Ойойой, не слушайте его, он вас плохому научит! :lol:
По идее модель в комбобоксе и модель в дереве слева - это должна быть одна и та же модель.
Поэтому индекс от одного должен подходить к индексу от другого.

Т.е. вы сначала получаете выделенный индекс от дерева
(назовем его 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
  Теперь я поняла тебя. :)
Вариант неплох, и вроде как даже проще в реализации.

Всё, вопрос пока снимаю. Знаю как реализовывать! :yahoo:
Алексей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;


У тебя этой очень удобной детальки , похоже, нету, поэтому мы не и понимаем друг друга :D В контейнере всё ищется и перебирается запросто
poluna Дата 16.12.2015, 12:10
  И я о том же!
Видимо я не так выражаюсь.
Прикрепленное изображение

На картинке, показано, что у меня есть.
В диалоге "Создание группы" указывается, родитель он должен быть выбран таким же, как и выделенный в левом дереве основного окна.
А я пока могу выбрать только ветки первого уровня.
Так надеюсь понятней, что мне нужно. :)

Или я тебя не понимаю! :D
Алексей1153 Дата 16.12.2015, 11:31
 
Цитата(poluna @ 16.12.2015, 13:27) *
Мне просто нужен комбобокс с деревом

так он же уже есть, как я понял )) Осталось обработку в дерево добавить
Просмотр темы полностью (откроется в новом окне)
RSS Текстовая версия Сейчас: 5.3.2021, 13:45