LINUX.ORG.RU

Тупых вопросов про Qt тред

 , , ,


0

1
  1. Что считается более труЪ и почему - инстанциировать библиотечные классы или наследоваться от них? Дилемма осложняется тем, что в Python модуль практически синглтон, т. е. если я в нем инстанциирую библиотечный класс и навалю вокруг полученного объекта своей логики как module-level функций, то я могу потом импортировать весь модуль и работать с ним как с объектом.

  2. Некоторые вещи в Qt можно сделать разными способами. Например, если нужно обрабатывать выбор элемента в дереве, то можно повесить свой обработчик на сигнал selectionModel().currentChanged, а можно перегрузить существующий обработчик currentChanged. Зачем так сделано и какой способ труЪ?

1. У тебя Qt из питона дергается? При чём тут питон? Вообще по ситуации, если не надо логику объекта менять, то инстанцируйся, если надо, то наследуйся.

2. Потому что C++ разрешает стрелять себе в ногу кучей способов. Как хочешь, так и стреляй. Но вообще в твоей ситуации лучше вешать обработчик, потому что перегрузка тебе ни нафиг не сдалась.

А вообще подожди C++ программистов, а не питонистов, которые C++ могут конечно использовать, но не глубоки в нём. И тег C++ повесь, Qt для Python-а это так, побочка.

peregrine ★★★★★ ()
Последнее исправление: peregrine (всего исправлений: 1)
Ответ на: комментарий от peregrine

если не надо логику объекта менять

Как понять, следует ли считать логику логикой объекта? Вот, например, мне надо, чтоб:

  • tree view сразу заполнялся элементами из некоторого источника
  • при выборе команды меню «обновить» - происходило запоминание текущего выбора элемента, очистка модели, повторное заполнение и восстановление выбора, если элемент с соотв. данными снова появился в модели.
  • при выборе элемента в дереве - отправлялся сигнал в другой виджет, заставляющий его показать подробности о выбранном элементе
  • при добавлении нового элемента в модель по сигналу из другого потока - он автоматически выбирался в tree view

Можно ли считать это изменением логики базового QTreeView, которую следует описать в методах производного класса?

Но вообще в твоей ситуации лучше вешать обработчик, потому что перегрузка тебе ни нафиг не сдалась.

А почему? А в какой ситуации сдалась перегрузка?

shatsky ★★ ()
Ответ на: комментарий от shatsky

1 Зависит от твоего опыта и предпочтений

2 Лично я придерживаюсь принципа KISS, он не идеален, но если что-то можно сделать просто, то не надо усложнять себе жизнь.

peregrine ★★★★★ ()
Ответ на: комментарий от shatsky

наследоваться еcтесcтвенно. все классы, что не должны наследоваться обозначаются как final. в нормальном ооп - наследование и доопределение - основной метод реализации. тебе по-любому надо иметь кастомный контрол, что совместим с базовым классом контролов, потому(если ты не хочешь наследоваться), либо ты должен сам сгородить свой контрол, полностью идентичный treeView в данном случае, либо отнаследоваться от имеющегося, и доопределить его так как тебе надо. это если делать в с++

alysnix ()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от shatsky

мне надо, чтоб

Я конечно лет 10 как не подходил Qt, но ЕМНИП, для всего этого ничего менять не нужно, только накидать соответствующих обработчиков.

изменением логики базового QTreeView

А что там за «логика»? Оно же только рисует и сигналы кидает по событиям.

no-such-file ★★★★★ ()
Ответ на: комментарий от no-such-file

Я конечно лет 10 как не подходил Qt, но ЕМНИП, для всего этого ничего менять не нужно, только накидать соответствующих обработчиков.

допустим ты пишешь аппу, где модуль экспортирует контролы - «дерево файлов», «дерево опций», и еще пять деревьев чего-то там. куда ты там «накидаешь обработчиков», и в каком виде ты это будешь выдавать наружу? разумеется просто пишутся специфические наследники от дерева, что и реализуют дерево файлов, дерево опций и так далее.

alysnix ()
Ответ на: комментарий от alysnix

наследоваться еcтесcтвенно. все классы, что не должны наследоваться обозначаются как final.

Мы про C++ говорим, а не про Java. Тут всё куда более безобразно. Автор C++ ничего про final не знает и знать не хочет. По крайней мере в той версии C++ из которой растут ноги у Qt. А если переписывать Qt на final, то там всё поломается внутри.

peregrine ★★★★★ ()
Последнее исправление: peregrine (всего исправлений: 3)
Ответ на: комментарий от alysnix

Я очень не уверен, что 5 разным объектам от дерева нужны одинаковые обработчики для отрисовки. А то что внтури Qt оно уже как-то унаследовано - нас не беспокоит из-за инкапсуляции.

peregrine ★★★★★ ()
Последнее исправление: peregrine (всего исправлений: 3)
Ответ на: комментарий от no-such-file

А что там за «логика»? Оно же только рисует и сигналы кидает по событиям.

А мне нужно, чтоб он еще делал все мной перечисленное - например, автоматически выбирал новый элемент. Для конкретики, мой класс DevicesView, о котором речь: https://github.com/shatsky/niudu-playground/blob/module-level-to-class/niudu-devices/ui_devices_view.py#L123 (это проект девайс менеджера, в котором инстанциируемый из этого класса виджет кажет дерево устройств /sys/devices/)

shatsky ★★ ()
Ответ на: комментарий от peregrine

Мы про C++ говорим, а не про Java.

вы отстали от с++ на 9 лет минимум

https://en.cppreference.com/w/cpp/language/final

final specifier (since C++11)

Specifies that a virtual function cannot be overridden in a derived class or that a class cannot be inherited from. Syntax

When applied to a member function, the identifier final appears immediately after the declarator in the syntax of a member function declaration or a member function definition inside a class definition.

When applied to a class, the identifier final appears at the beginning of the class definition, immediately after the name of the class.

alysnix ()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от alysnix

А теперь сморим на то, когда Qt вышла в том виде, в котором она сейчас. Подсказка, Qt 5 не шибко отличается в плане архитектуры от Qt 4, которые вышли в 2005 году. Программы с Qt4 легко портируются на Qt5, порой достаточно только include поменять.

peregrine ★★★★★ ()
Ответ на: комментарий от shatsky

В Qt контролы, которые отображают данные, принято разносить на вьюху и модель.

а понял.

это почему мне больше нравится wxWidgets.. судя по всему надо наследоваться от вью. хотя надо смотреть на архитектуру такого представления

alysnix ()
Последнее исправление: alysnix (всего исправлений: 1)
  1. Не надо наследоваться. Ты просто используешь виджет, а не изменяешь его поведение или функциональность.

  2. Вешать обработчик на сигнал. Именно такой способ использования виджетов предполагают разработчики Qt.

Внутрь нужно лезть только если по другому никак.

ox55ff ★★★★ ()
Ответ на: комментарий от alysnix

это почему мне больше нравится wxWidgets.. судя по всему надо наследоваться от вью.

Охоссподи. Прямо «не читал но осуждаю» какое-то.

Если использовать QTreeView/QTableView/QListView, наследоваться от него не надо. Надо подсунуть ему нужную модель. Вот её можно унаследовать от одной из абстрактных, для некоторых случаев (работа с SQL, например) можно взять готовую.

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

Для тех же, кто любит работать напрямую с виджетом, есть QTreeWidget/QTableWidget/QListWidget. Заполняйте его ручками, сколько влезет. Там в ячейки пихать можно что угодно. Но возможные косяки, связанные с производительностью, разруливайте сами. Эти виджеты хороши, когда строк немного, и их нужно просто тупо вывести.

И ещё момент. Я в QML мимокрокодил, но насколько я понимаю, если ты заложил логику в модели, эти модели будут работать и с QML, и с QtWidgets. То есть можно программе сделать два UI с одним ядром. Прямая работа с виджетами, разумеется, прибита гвоздями к QtWidgets.

Ниже правильно написали:

Внутрь нужно лезть только если по другому никак.

P.S. Наследоваться от виджетов, конечно же, можно. Только при этом начинается некоторый геморрой, если ты окно собираешь дизайнером.

hobbit ★★★★★ ()
Последнее исправление: hobbit (всего исправлений: 1)
Ответ на: комментарий от shatsky

например, автоматически выбирал новый элемент

И в чём проблема? Делаешь отдельный контроллер, через который будешь менять модель вьюхи и в нём следишь за тем что было выбрано (по сигналам вьюхи) и автовыбираешь элемент в новой модели, если он есть.

no-such-file ★★★★★ ()

Погрепал код трех самых известных приложений, использующих PyQt - OpenShot, Calibre и QGIS. Результаты:

  • QTreeView не инстанциируется нигде, везде от него наследуются свои классы
  • currentChanged перегружается у тех классов, у которых он есть (кроме QGIS, в котором всегда используется selectionModel().currentChanged.connect())
  • слово «controller» не встречается в чем-либо, похожем на класс для управления поведением вьюхи; логика поведения описывается в унаследованном от вьюхи классе, который обычно называется {Название_отображаемой_сущности}View

Вроде как похоже на то, к чему пока что пришел я.

shatsky ★★ ()
Ответ на: комментарий от shatsky

Погрепал код трех самых известных приложений, использующих PyQt

Это всего лишь значит, что пользователи PyQt лютые говнокодеры. Ну или пЕтон вынуждает говнокодить. Это верно безотносительно качества и полезности конечного результата. Говнокодеры на жабоскрипте тоже много чего полезного пишут, но говна там будь здоров.

ox55ff ★★★★ ()
Ответ на: комментарий от ox55ff

Не вынуждает. Просто связку Qt и C++ не тянут из-за низкого вхождения в питон и бешенного в кресты. Максимум к чему привыкли - Qt + C, при том так, чтобы код на C по питонячьи был написан.

anonymous ()