LINUX.ORG.RU

Написание виджетов на pyqt5 без ооп

 , , , ,


1

1

Доброго времени суток. Мне понадобилось написать виджет круглого прогрессбара. Как это можно сделать без ООП? Я понимаю что в qt всё на ооп завязано, но можно без всяких self, class? (Написать на пайтоне) Вы можете, спросить, почему я не юзаю ООП, я отвечу: «Я просто не смог разобраться в ооп, поэтому всячески его избегаю». В статьях из инета везде копипаста. А некторые просто не открываются.



Последнее исправление: enot_obrmot (всего исправлений: 1)

Ответ на: комментарий от enot_obrmot

А можно селфа чтобы не было? Просто меня это бесит, нужно тратить время на написание этого слова

Проблема явно не в self.

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

Конкретно в твоем примере развесистые объекты Qt, н чего не поделать

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

А в том что у меня код на ооп с первого раза никогда не работает

Вы хотите, чтобы вас пожалели? Ну у меня тоже часто с первого раза код не работает. И со второго раза тоже, бывает. Ну и?

qaqa ★★
()

ООП простое как валенок, по крайней мере для твоих двух формочек.

Для пистона есть всякие ткинтеры, они ЕМНИП без ООП.

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

Йоптыть, ну ты бы хотя бы почитал, что такое ООП и как это работает на уровне абстракий. А потом уже писал селфы и классы.

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

Лично мне понять ООП очень помогло чтение книги «Структура и интерпретация компьютерных программ», особенно третья глава «Модульность, объекты и состояние».

czan
()
Ответ на: комментарий от anonymous-angler

Лор не перестаёт привлекать самых жирных троллей (:

Кормють… Где б меня на халяву кормили – я б тоже там поселился.

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


class Person:
def __init__(self, name, age):
self.name = name
self.age = age

def myfunc(self):
print(«Hello my name is » + self.name)

p1 = Person(«John», 36)
p1.myfunc()


Self это особенность питона. Он позволяет в теле метода обращаться к свойствам самого объекта. Без него никак. Первый параметр в методах классов всегда идёт ссылка на сам класс, и это self. Этот параметр можно назвать по другому, например s, но потом в теле метода тоже нужно писать s.name.

Главное понять различия класса и объекта. Класс только описывает как объект выглядит и какие функции и как должен выполнять. Это как генная информация у людей.

Чтобы им воспользоваться нужно из класса создать объект. Предпоследняя строчка в коде. Это где круглые скобки.

Потом к созданному обьекту можно обращаться. Можно запрашивать переменные или вызывать функции. Это последняя строчка.

Название класса принято писать с большой буквы, объектов с маленькой.

Тут в примере ещё и инит есть. Это конструктор, он позволяет при создании объекта задать ему какие-то начальные параметры. Но он не всегда обязателен.

Пример взял отсюда https://www.w3schools.com/python/python_classes.asp

kontranik
()
Последнее исправление: kontranik (всего исправлений: 2)

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

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

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

бред собачий

От человека с собачкой с аватарке звучит забавно.

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

Он позволяет в теле метода обращаться к свойствам самого объекта. Без него никак.

Прикольно. В плюсах и объектном паскале this/self нужен далеко не всегда. Хотя смысл его в целом тот же.

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

В плюсах скрытие this не более чем синтаксический сахарок, емнип в некоторых code style его требуют писать явно всегда.

В питоне, поскольку есть объекты/экземпляры класса и bound/unbound методы self решили сделать обязательным, и это пожалуй правильно.

Статические поля в питоне, вот что может сломать неофиту весь мозг:-)

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

Circle.draw(circle) – это масляное масло.

Circle.draw(rectangle) – это вообще ошибка, но синтаксически корректно. Прекрасное решение, особенно для динамически-типизированного языка.

circle.draw() – это нормальный ООП.

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

Можно придумать защиту от дурака, но только от неизобретательного.

Внезапно в плюсах, где this передается неявно, возможны все три варианта.

Зато передача bound/unbound методов в питоне выглядит куда более прямо.

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

Где б меня на халяву кормили – я б тоже там поселился.

И женщины бы ласки дарили без долгих ухаживаний, да?..

Хотя нет. Мужчина, сцуко, так устроен, что такие ласки обычно оказываются не оцененными по достоинству.

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

Можно придумать защиту от дурака, но только от неизобретательного.

Если это про Circle.draw(rectangle), то изобретательность тут не при чём. Это общая проблема всех динамически типизированных языков, в данном случае я её просто наглядно подсветил.

Зато передача bound/unbound методов в питоне выглядит куда более прямо.

В питоне я не силён. Пытался изучать года 3 назад – с одного туториала два экрана претензий в блокнотик набралось. Через пару месяцев наткнулся, глянул печально и стёр. Не моё, в общем. Так что теперь поди вспомни, что такое bound-методы.

Внезапно в плюсах, где this передается неявно, возможны все три варианта.

А вот где в плюсах явная передача this в не-статические методы класса – посмотрел бы с удовольствием. Разве что как обычным дополнительным параметром в обычную функцию – но это и не ООП нифига, это C-style эмуляция без полиморфизма (хм, вернее без vtable; параметр-то можно подсовывать полиморфный, если указателем/ссылкой). Ну ещё совсем изредка бывают нетипичные хаки когда из static-метода вызывается не-static (e.g. thread-функция с экземпляром передаваемым через void* параметр, делегирующая к не-static методу).

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

Хотя нет. Мужчина, сцуко, так устроен, что такие ласки обычно оказываются не оцененными по достоинству.

Depends. Случается и родственную душу найти. И в любом случае это гораздо лучше, чем долгие ухаживания с нулевым эффектом.

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

Это общая проблема всех динамически типизированных языков

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

что такое bound-методы

Cirle.draw - unbound, cirle.draw - bound. Во втором случае в методе (который вызываемый объект) спрятан self. Вообще изучение питона очень просветляет насчет устройства ООП.

А вот где в плюсах явная передача this в не-статические методы класса – посмотрел бы с удовольствием.

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

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

Cirle.draw - unbound, cirle.draw - bound. Во втором случае в методе (который вызываемый объект) спрятан self. Вообще изучение питона очень просветляет насчет устройства ООП.

А по-моему это нагромождение терминологии на ровном месте. «Философия – наука усложнять простые вещи.» Так себе просветление. Хотя конечно разным людям могут быть понятнее разные объяснения одних и тех же вещей.

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

Ох ты ж блин. Холмс, но зачем?! То что на C/C++ можно творить любую дичь – это конечно прекрасно, но в такие моменты надо всегда чётко осознавать и каментить: вот здесь и сейчас я творю дичь.

Но у плюсов синтаксис таких вещей совершенно жуткий.

У плюсов синтаксис вообще жуткий. Но в данном случае – и слава богу, ибо нефиг.

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

Любой нестатический метод класса штатно кастуется руками к обычной функции с первым дополнительным аргументом - указателем на экземпляр класса

Как именно?

Мне кажется эти касты не будут всегда работать, нужно использовать mem_fn (https://en.cppreference.com/w/cpp/utility/functional/mem_fn)

Пример: https://gcc.godbolt.org/z/qnWv69qfv

@dimgel

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

можно творить любую дичь

В т.ч. можно взять reinterpret_cast и легко подсунуть rectangle вместо circle. И расстраиваться, почему эта дрянь сегфолтится не пойми от чего. :D

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

Я не любитель стандарты читать, но здравый смысл подсказывает что он прав: через регистры или через стек, первый аргумент есть первый аргумент, пофиг явный или неявный. По крайней мере на x86-64. (UPD: Смутно вспоминается, что на x86-64 первый аргумент всегда идёт через регистр, перечитывать вику впрочем лень, как и пробовать в godbolt.)

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

но здравый смысл подсказывает что он прав: через регистры или через стек, первый аргумент есть первый аргумент, пофиг явный или неявный

member function pointer может иметь даже разный размер по сравнению с обычным function pointer согласно стандарту, но вроде в реализациях там совпадает.

Ещё там разные calling convensions: __cdeclи __thiscall

Может и ещё различия есть.

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

А по-моему это нагромождение терминологии на ровном месте

Это только по Вашему. В питоне bound/unbound методы это существенно разные вещи, как и объект класса (Circle)/экземпляр класса (circle), поэтому там требуется соответствующая терминология. В С++ объектов класса нет и bound методов нет, поэтому и терминологии нет.

Эскимосу тоже кажется, что терминология квантовой физики излишне сложная, а PhD из MIT кажется слишком сложной эскимосская терминология по поводу видов снега.

Ох ты ж блин. Холмс, но зачем?!

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

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

Во первых затем, что это именно делает компайлер, и неплохо понимать что именно он делает.

Нерелевантно. Компайлер вон ассемблер генерит, но знание ассемблера нужно 0.001% прикладников.

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

typedef void (Class::*MemberPtr)(...); или

using MemberPtr = void (Class::*)(...);

или микширования вызова методов и обычных функций

Ну ок. Случаи разные бывают.

Меня вообще вопрос «зачем?» вводит в ступор - вот есть у ЯП такая возможность, нужно - юзай, ненужно - не юзай.

Вопрос законный сразу по двум причинам, причём НЕ взаимоисключающим: (1) интересно; (2) далеко не все возможности надо использовать (0:43-1:18).

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

Нерелевантно. Компайлер вон ассемблер генерит, но знание ассемблера нужно 0.001% прикладников.

Вы путаете понимание и знание, это все таки разные вещи.

using void (Class::*memberPtr)(…); или как-то так.

синтаксис вызова обычной функции по указателю и функции-члена по указателю разный. А иногда нужно что бы был одинаковый.

Я такими вещами давно не занимаюсь, но когда то это было актуально и это был такой штатный лайфхак.

далеко не все возможности надо использовать

Потребности у всех разные. Попытка делать выводы на основе лично своих потребностях о потребностях всех остальных… вот это точно не надо делать.

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

синтаксис вызова обычной функции по указателю и функции-члена по указателю разный. А иногда нужно что бы был одинаковый.

Я такими вещами давно не занимаюсь, но когда то это было актуально и это был такой штатный лайфхак.

Понятно.

Попытка делать выводы на основе лично своих потребностях о потребностях всех остальных… вот это точно не надо делать.

Ну ок.jpeg :)

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

На сайте исо спп нашел заметку по этому поводу: https://isocpp.org/wiki/faq/pointers-to-members

NOTE: do not attempt to “cast” a pointer-to-member-function into a pointer-to-function; the result is undefined and probably disastrous. E.g., a pointer-to-member-function is not required to contain the machine address of the appropriate function. As was said in the last example, if you have a pointer to a regular C function, use either a top-level (non-member) function, or a static (class) member function.

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

Лет… 10-15 назад это работало без проблем. Хотя gcc4.8.5 тоже че то там предупреждает, может я немного криво сделал, забыл уже детали.

Сейчас наверное есть какие то штатные средства что бы так извращаться в этих новомодных С++ХХL

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

E.g., a pointer-to-member-function is not required to contain the machine address of the appropriate function.

Недурно. Т.е. на какой-нибудь архитектуре это может быть например большой адрес объекта + маленький индекс в vtable? Хм, но функция может быть невиртуальной. Впрочем, у невиртуальных и виртуальных функций модель адресации может быть разной.

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

ну началось… Ок, можно написать обертку для пойнтера (если ее уже не написали в std). Ох уж эти плюсы.

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

Сейчас наверное есть какие то штатные средства что бы так извращаться в этих новомодных С++ХХL

Смотря что нужно сделать. Самое похожее что приходит в голову это mem_fn:

https://en.cppreference.com/w/cpp/utility/functional/mem_fn

fsb4000 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.