Russian Qt Forum

Qt => Model-View (MV) => Тема начата: Tonal от Июнь 19, 2007, 10:16



Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Tonal от Июнь 19, 2007, 10:16
Может кто такое уже делал?
Вроде ничего сложного:
  • создаёшь QTreeView,
  • устанавливаешь ему модель,
  • устанавливаешь его в качестве view в комбике,
  • устанавливаешь комбику ту же модель.

Оно даже показывается.
Но при выборе любого элемента дерева currentIndex не меняется, и при открытии снова в дереве не установлен текущий элемент...

Как побороть?


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: SABROG от Июнь 19, 2007, 10:52
Т.е. он каждый раз заново его создает ?


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Tonal от Июнь 19, 2007, 12:09
Нет, с чего бы это.
Просто он, похоже не умеет корректно обрабатывать выбор в дереве.
Или я его не умею об этом правильно попросить. ;-\


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: SABROG от Июнь 20, 2007, 08:37
А выбранный элемент не появляется в поле комбика после того как список закрылся ?


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Tonal от Июнь 20, 2007, 08:47
Там вообще какая-то лажа...
Тестировалось на дереве с одним корнем.
Так вот, если выбрать итем из первой ветки - пишется корень
Если из какой другой - пусто.

P.S. Понятно, что в исходники надо лезть и разбираться. Но пока времени нет... ;-(


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Tonal от Июнь 26, 2007, 10:01
Разобрался.
Если кратко, надо переопределить showPopup и hidePopup у QComboBox-а

Если кому интересно, могу кинуть сюда код на python-е - аж ~60 строк. ;-)


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Gryz от Июнь 26, 2007, 13:44
Кидай, что вышло. В будущем может пригодиться. :)


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Racheengel от Июнь 26, 2007, 13:58
Мы на конторе тоже делали подобную дрянь... тока комбо сами отрисовывали, ну и своего управления подобавляли. Там проблема в сохранении индекса элемента дерева была - надо было всегда сохранять индекс для 0-й колонки, а по умолчанию возвращался индекс итема для той колонки, где он был выбран...


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Tonal от Июнь 26, 2007, 14:04
Код:

from PyQt4 import QtCore, QtGui

class WidgetComboBoxTree(QtGui.QTreeView):

  def __init__(self, parent=None):
    QtGui.QTreeView.__init__(self, parent)
    self.setUniformRowHeights(True)
    self.setRootIsDecorated(True)
    self.setItemsExpandable(True)
    self.setSortingEnabled(True)
    self.setSelectionBehavior(QtGui.QTreeView.SelectRows)
    self.header().setVisible(False)
    self.setMinimumHeight(150)

class WidgetTreeCombo(QtGui.QComboBox):
  __curItem = None
  __tree = None

  def __init__(self, parent=None):
    QtGui.QComboBox.__init__(self)
    self.__tree = WidgetComboBoxTree()
    self.setView(self.__tree)

  def hidePopup(self):
    self.__setCurModInd(self.view().currentIndex())
    return QtGui.QComboBox.hidePopup(self)

  def showPopup(self):
    QtGui.QComboBox.showPopup(self)
    self.setRootModelIndex(QtCore.QModelIndex())
    self.__tree.expandAll()

  def currentModelIndex(self):
    return self.__curItem

  def setModel(self, model, sortOrder=QtCore.Qt.AscendingOrder):
    if sortOrder in (QtCore.Qt.AscendingOrder, QtCore.Qt.DescendingOrder):
      self.__tree.header().setSortIndicator(0, sortOrder)
    QtGui.QComboBox.setModel(self, model)

  def setCurrentModelIndex(self, modelIndex):
    self.__setCurModInd(modelIndex)
    self.setCurrentIndex(modelIndex.isValid() and modelIndex.row() or 0)

  def tree(self):
    return self.__tree

  def __setCurModInd(self, idx):
    if idx and idx.isValid:
      self.__curItem = QtCore.QPersistentModelIndex(idx)
      self.setRootModelIndex(self.__curItem.parent())
    else:
      self.__curItem = None
      self.setRootModelIndex(QtCore.QModelIndex())

Несколько замечаний:
1) Здесь предполагается, что хотя бы один элемент в дереве да есть.
2) Честно расчитывать размер мне пока лень. ;-)
3) Цвет дерева в Cleanlooks-е почему-то не такой как у обычного списка для не редактируемого комбобокса.
4) При попытке свернуть/развернуть ветку, её корень выбирается и список закрывается.


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Racheengel от Июнь 26, 2007, 22:09
блин, что за мракобесие этот питон...


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Tonal от Июнь 27, 2007, 08:21
А что не нравиться-то?
Как было, так и запостил.
Перепиши на плюсы - тут практически 1в1 можно сделать. Кода только чуть больше получиться ;-)

P.S. Я люблю плюсы, и довольно хорошо их знаю, но, к сожалению, по скорости разработки и простоте поддержки python-у они сливают ощутимо.
P.P.S. Python я тоже люблю и б/м знаю. ;-)


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Racheengel от Июнь 27, 2007, 08:52
да синтаксис у него какой то уезженный... такое чувство, что на бейсик перешел... А по скорости разработки и простоте что плюсы уступают - я не соглашусь.


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Tonal от Июнь 27, 2007, 16:45
Ну синтаксис - это кому что нравиться. Меня вот с басика корячит, а в MS его очень любят. ;-)

А про скорость разработки и простоте - это реально так...
Достигается многими факторами: простота языка, базовые структуры данных, объектные и функциональные возможности, сборка мусора, богатство стандартной библиотеки, стак-трейс, и т.д.

Я как-то здесь более подробно всё расписывал.

У нас раньше разработка велась в основном на Delphi и CBuilder-е.
Он из за бардака в borland-е мы постоянно искали альтернативы.
А тут заказик подошел - сделать прогу - помошник переводчика одной очень специализированной базы данных.
Базка - 100м в dbf-ах с иерархической структурой.
Заказик небольшой и не критичный.
Решили посмотреть, как это на Qt получиться.
Набросали прототип на Python + Qt, чтоб потом, как юзабилити и функциональность утрясётся, на плюсы переписать, чтоб не тормозило...
Переписывать не пришлось - скорость работы заказчика полностью удовлетворила! ;-)

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


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Racheengel от Июнь 27, 2007, 20:41
Delphi и CBuilder - отстой редкий... особенно последнее...
Питон же мне васика напоминает всем, а именно производительность, а не скорость разработки играет решающую роль, по крайней мере у нас.
Тут уж лучше плюсов может быть только асм :)


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Tonal от Июнь 27, 2007, 21:46
Цитата: "Racheengel"
Delphi и CBuilder - отстой редкий... особенно последнее...

Полностью согласен. Написал им более 10 багрепортов... А в ответ - тишина...
Но хотелось бы какой-нибудь конкрктный пример "отстоя", на плюсах желательно, строк на 3-5, чтобы убедиться что ты в курсе того о чём говоришь.
Цитата: "Racheengel"
Питон же мне васика напоминает всем

На вкус и цвет... А много ли ты писал на том или другом?
Вобще на чём кроме плюсов? ;-)
Цитата: "Racheengel"
, а именно производительность, а не скорость разработки играет решающую роль, по крайней мере у нас.
Тут уж лучше плюсов может быть только асм :)

Это всяко от задачи зависит.
На совсем вычислительных задачах до сих пор Fortran рулит вроде как. ;-)
Ну а если, например, клиентский гуй рисовать, так по любому тормоза основные на сервере да на сетке будит. Так что примерно пофиг скорость выполнения языка. Хотя, если нет привычки голову включать, то и на плюсах всё будет тормозить. ;-)


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Racheengel от Июнь 28, 2007, 08:35
Цитировать

Полностью согласен. Написал им более 10 багрепортов... А в ответ - тишина...
Но хотелось бы какой-нибудь конкрктный пример "отстоя", на плюсах желательно, строк на 3-5, чтобы убедиться что ты в курсе того о чём говоришь.


Пример прям щас не подгоню, но там все мрачно выглядит... Чего стоят одни эти Properties... Билдер - это вообще микс С++ и паскаля. Здоровенный монстр, тормознутый и кривой. Часто собранная ехе в конце работы пишет runtime error... Это особенно если всякий мрак типа СОМ с ним юзать.

Цитировать

На вкус и цвет... А много ли ты писал на том или другом?
Вобще на чём кроме плюсов?


Много на чем писал... С\С++, Asm, Delphi, Java, JSP, PHP... немного Ада затрагивал по одному проекту... Но, честно говоря, больше предпочтений все равно плюсам - как языку с намного большими возможностями.
Если писать под десктоп - это самое оно.
Если под веб - больше РНР уважаю.
А все эти новомодные Руби, Питоны... ну странное оно все какое-то... Языки решают задачи, которые до их появления не существовали ИМХО...


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Tonal от Июнь 28, 2007, 10:33
Цитата: "Racheengel"
Цитировать
...хотелось бы какой-нибудь конкрктный пример "отстоя"...
чтобы убедиться что ты в курсе того о чём говоришь.

Пример прям щас не подгоню, но там все мрачно выглядит...

Жаль. А я уж решил что ты действительно знаешь о чём говоришь. ;-(
Там призабавные перлы как раз строчек на 3-5 встречаються... ;-)
Цитата: "Racheengel"

Чего стоят одни эти Properties... Билдер - это вообще микс С++ и паскаля. Здоровенный монстр, тормознутый и кривой. Часто собранная ехе в конце работы пишет runtime error... Это особенно если всякий мрак типа СОМ с ним юзать.

Проперти - эт. нормально вполне. Кстати и не багландом а микрософтом придуманы и реализованы.
И на чистом плюсе строк в 20 укладываються. ;-)
А насчёт runtime error в конце - так это вполне классическая ошибка криворуких кодеров. Причём это проблема VCL-я а не Builder-а или Delphi. Довольно просто отлавливается, если знать куда смотреть.
Думаю и на Qt подобного вполне можно добиться, если не следить за зависимостями. Хотя в VCL-е этого конечно проще добиться...
Не написав не строчки кода! ;-)
Цитата: "Racheengel"

А все эти новомодные Руби, Питоны... ну странное оно все какое-то... Языки решают задачи, которые до их появления не существовали ИМХО...

Вот простенькая задачка:
Написать функцию которая по входной строке целых чисел разделённых пробелами возвратит строку из квадратов этих чисел разделённых пробелами.
Вот, решение на Python:
Код:

def str_sqare(s_in):
 return ' '.join(int(x)*int(x) for x in s_in.split())

Вроде вполне нормальная задачка - вполне до появления Python-а могла возникнуть.
Нарисуй аналог на том же плюсе или php. ;-)
И сравним, кто более выразительный.


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Steven_Orko от Июнь 28, 2007, 11:02
Че вы спорите???? Вы сравниваете два языка совершенно разного поколения!!!! О чем вообще может идти речь??? Аналог вашего спора - это спор между любителем писать в машинных кодах и на языке C.
Python (http://ru.wikipedia.org/wiki/Python) -  интерпретируемый объектно-ориентированный язык программирования высокого уровня.
Современный С++ (http://ru.wikipedia.org/wiki/С++) - компилируемый строго типизированный язык программирования общего назначения.
Хотя, может Tonal пытается доказать, что он умнее, опытнее Racheengel? Это уже оффтоп.


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Racheengel от Июнь 28, 2007, 11:25
Поверь мне, я знаю, о чем я говорю. Я писал на делфе где-то с 2000 по 2004 год. Потом, в 2004, перешел на Qt, о чем нисколько не жалею. Последний дельфовый проект пришлось делать где-то год назад (с большими матами, причем это был порт чужого глючного кода), так что естественно, что я уже не вспомню конкретные проблемы, для этого надо лезть в давно забытые архивы.
Может, ты сам таки кинешь 3-5 строк кода? :)

А вот решение на С++/Qt.

Код:
QString str_square(const QString &s_in)
{
  QTextStream ts(&s_in);
  QString s;
  QTextStream ts2(&s);
  double d;
  while (!ts.atEnd()) {
     ts >> d; s << d*d << " ";
  }
  return s;
}



Не знаю, что имеется в виду под выразительностью, но кутишный код имхо проще и понятнее по смыслу. Все разбито на логически завершенные элементы.
Чего не могу сказать про питон. Там все намешано в кучу.

добавлено спустя:

 Вдогонку: да, я могу согласиться, что на Питоне код получится поменьше.
Но как правило, конечному пользователю плевать, сколько в программе кода и на чем она писана. Главный показатель - это эффективность, и тут уж плюсы уступят только асму. Сколько, к примеру, времеми займет данный пример на питоне, примененный к миллиону строк, в каждой из которой по тысяче цифр? А на плюсах? :)


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Tonal от Июнь 28, 2007, 12:27
Цитата: "Racheengel"
Может, ты сам таки кинешь 3-5 строк кода? :)

Легко:
Код:

struct test_t {
  test_t() : {cout<<"test_t"<<endl;}
  ~test_t() {cout<<"~test_t"<<endl;}
};
int main() {
  return sizeof test_t(666);
}
//вывод
~test_t

Чёрт, на 2 строки больше! ;-)
Цитата: "Racheengel"
А вот решение на С++/Qt...

Мне больше так нравиться:
Код:
QString str_square(const QString &s_in) {
  QStringList tmp;
  foreach (QString str, s_in.trimmed().split(QRegExp("\\s+"))) {
    int i = str.toInt();
    tmp.push_back(QString::number(i * i));
  }
  return tmp.join(" ");
}


Похоже действительно пора завязывать с этим трёпом.
Совсем офтоп пошел. ;-)


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Racheengel от Июнь 29, 2007, 10:03
Ага :) завязываем. А то начали про комбо-дерево, а закончили какой то лажей...

PS. А 1й пример не скомпилится :(


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: SABROG от Июнь 29, 2007, 13:07
Насчет раскрытия дерева при клике на корень. Можно использовать правую кнопку мышки вместо левой.


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Tonal от Июль 01, 2007, 13:32
Цитата: "Racheengel"
PS. А 1й пример не скомпилится :(

Ну там понятно нужно iostrem заинклюдить, да using сделать.
Я только сам код привёл.

Аналогичные ляпы у них с typeid и даже с тернатным оператором и статиками можно наткнуться... ;-(
Хотя статики они починили.


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Racheengel от Июль 01, 2007, 16:06
не, не поэтому...

sizeof test_t(666);

а конструктора с параметрами нету. sizeof test_t(); будет работать.

добавлено спустя 14 минут:

 ладно, что то все оффтопы да оффтопы...
скоро, надеюсь, выложу комбо-дерево на сайте... там же где и Value Browser (www.ii-system.com)


Название: Qt 4.2.3 Дерево в комбобоксе
Отправлено: Tonal от Июль 02, 2007, 07:29
Кстати, проблему с currentIndex я в показанном коде решил таким образом:
при закрыии устанавливаю rootItem в текущий выбранный, а при открытии - в корень (см __setCurModInd).
Тогда индекс комбика всегда соответствует индексу выбранного элемента. ;-)