TGTGInsighttelegram intelligenceLIVE / telegram public index
Назад кон каналите
Python Заметки avatar

TGINSIGHT CHAT

Python Заметки

@pythonotes

Education

Интересные заметки и обучающие материалы по Python Контакт: @paulwinex ⚠️ Рекламу на канале не делаю!⚠️ Хештеги для поиска: #tricks #libs #pep #basic #regex #qt #django #2to3 #source #offtop

Претплатници2,220Тековни претплатници
Следени објави384Број на индексирани објави
Неодамнешен опфат17,560Збир на неодамнешни прегледи
Неодамнешни објави

Неодамнешни објави

Ознака: #qt · 17 објави

当前筛选 #qt清除筛选

Објавено 23 окт.

А вот и наглядное использование контроля стилей через свойства виджета. Билиотека qt-material. В этом разделе написано, что через свойство class можно контролировать цвет кнопки, по аналогии с css стилями. btn_danger.setProperty('class', 'danger') btn_warning.setProperty('class', 'warning') btn_success.setProperty('class', 'success') #libs#qt

1,490 views

Hashtags

Објавено 23 окт.

Установить свойства виджета в PySide можно не только через соответствующие методы и конструктор класса. Можно их изменять с помощью метода setProperty по имени. btn = QPushButton("Click Me") btn.setProperty("flat", True) Это аналогично вызову btn.setFlat(True) Если указать несуществующее свойство, то оно просто создается btn.setProperty("btnType", "super") Получить его значение можно методом .property(name) btn_type = btn.property("btnType") Когда это может быть полезно? ▫️Можно просто хранить какие то данные в виджете и потом их доставать обратно widget = QWidget() widget.setProperty('my_data', 123) print(widget.property('my_data')) ▫️ Назначая эти свойства разным виджетам можно потом отличить виджеты во время итераци по ним. Например, найти все кнопки со свойством my_data="superbtn". Но ведь вместо кастомного свойства можно использовать objectName, будет тот же результат. Да, но y ObjectName есть ограничение - только строки. ▫️ Если нам потребуется не просто поиск а, например, сортировка по числу, то свойства позволяют нам это сделать. Поддерживается любой тип данных widget.setProperty('my_data', {'Key': 'value'}) widget.setProperty('order', 1) all_widgets.sort(key=w: w.property('order')) Но ведь Python позволяет всё вышеперечисленное сделать простым созданием атрибута у объекта widget.order = 1 widget.my_data = 123 Да, но я думаю что не надо объяснять почему не стоит так делать. К тому же, если у виджета нет свойства то метод .property(name) вернет None, а отсутствующий атрибут выбросит исключение. ▫️ Действительно полезное применение кастомным свойствам - контроль стилей. Здесь атрибутами не обойтись, нужны именно свойства. Дело в том, что в селекторах стилей можно указывать конкретные свойства виджетов на которые следует назначать стиль. Просто запустите этот код from PySide2.QtWidgets import * if __name__ == "__main__": app = QApplication([]) widget = QWidget(minimumWidth=300) layout = QVBoxLayout(widget) btn1 = QPushButton("Action 1") btn2 = QPushButton("Action 2") btn3 = QPushButton("Action 3", flat=True) layout.addWidget(btn1) layout.addWidget(btn2) layout.addWidget(btn3) # добавим кастомное свойство одной кнопке btn1.setProperty("btnType", "super") # добавляем стили widget.setStyleSheet( """ QPushButton[btnType="super"] { background-color: yellow; color: red; } QPushButton[flat="true"] { color: yellow; } """ ) widget.show() app.exec_() С помощью селектора мы избирательно назначили стили на конкретные кнопки. Как получить список всех кастомный свойств? Функция получения списка кастомных свойств отличается от получения дефолтных. def print_widget_dyn_properties(widget): for prop_name in widget.dynamicPropertyNames(): property_name = prop_name.data().decode() property_value = widget.property(property_name) print(f"{property_name}: {property_value}") #tricks#qt

1,150 views

Hashtags

Објавено 21 окт.

Регулярно приходится писать и ревьюить код, где используется PySide2-6. Заметил, что в подавляющем большинстве случаев настройка создаваемых базовых виджетов происходит через методы. Думаю, всем знаком такой способ. Простой пример с кнопкой: button = QPushButton("Click Me") button.setMinimumWidth(300) button.setFlat(True) button.setStyleSheet("font-size: 20pt") button.setToolTip("Super Button") button.clicked.connect(lambda: print("Button clicked")) Но есть и альтернативный способ - настройка через свойства. Это просто ключевые аргументы конструктора класса. Хоть они и не указаны в документации как аргументы, но они есть) Этот код делает тоже самое но с помощью Property button = QPushButton( "Click Me", minimumWidth=300, flat=True, styleSheet="font-size: 20pt", toolTip="Super Button", clicked=lambda: print("Button clicked"), ) Где это может быть полезно ▫️ Это выглядит более аккуратно и коротко, уже повод использовать ▫️ Может использоваться в заполнении лейаута, когда нам не нужно никакое другое взаимодействие с виджетом и поэтому сохранять его в переменную не требуется. Например, лейбл или кнопка. widget = QWidget(minimumWidth=400) layout = QHBoxLayout(widget) layout.addWidget(QLabel("Button >", alignment=Qt.AlignRight)) layout.addWidget(QPushButton("Click Me", clicked=lambda: print("Button clicked"))) widget.show() Либо так widget = QWidget(minimumWidth=400) layout = QHBoxLayout(widget) for wd in ( QLabel("Button >", alignment=Qt.AlignRight), QPushButton("Click Me", clicked=lambda: ...) ): layout.addWidget(wd) widget.show() ▫️ Можно хранить настройки в каком-то конфиге или генерировать на лету, после чего передавать как kwargs. kwargs = {"text": "Hello " * 30, "wordWrap": True} my_label = QLabel(**kwargs) Как получить полный список доступных свойств? Эта функция распечатает в терминал все свойства виджета и их текущие значения def print_widget_properties(widget): meta_object = widget.metaObject() for i in range(meta_object.propertyCount()): property_ = meta_object.property(i) property_name = property_.name() property_value = property_.read(widget) print(f"{property_name}: {property_value}") #tricks#qt

1,000 views

Hashtags

Објавено 6 окт.

Релиз Python 3.10 случился! Все быстро побежали использовать новые type hints, pattern matching и всё такое😁 А между тем, на днях вышел Qt6.2. Наконец-то портировали такие модули как QtBluetooth, QtMultimedia, QtWebEngine, QtWebView и другие полезняхи. Если вы этого ждали, то пора действовать! PySide6 тоже подтянулся по версии. #qt#libs

2,590 views

Hashtags

Објавено 9 апр.

🤩Разбираем полезные исходники! Функция, возвращающая словарь с данными о панели задач. screen : номер монитора location : расположение на экране (внизу, слева и тд) geometry : QRect с координатами таскбара system_tray : доступен ли системный трей 🔸 Как может пригодиться? Я использую для открытия виджета по клику на значке в трее с выравниванием по таскбару. Аналогично работает попап у Dropbox клиента. 🔸 Тестил на Windows10 и Debian10. 🔸 В комплекте проверочный виджет который при создании точно перекрывает таскбар. Проверка правильности определения геометрии таскбара. Закрывается по клику. 🔸 Ещё в комплекте пример окошка, которое появляется в районе часов над таскбаром. 🔸 Есть один баг. При перекрытии тасбара в Gnome (linux) виджет не получает событий от мыши. Решения пока не нашел😕 Код забираем здесь ↗️ #source#qt

1,740 views

Hashtags

Објавено 3 мар.

Несмотря на то, что проекты линейки Qt For Python (все версии PySide и PyQt) считаются полноценными production-решениями, они всё еще недоделаны и постоянно развиваются. В частности, не все классы оригинального С++ фреймворка реализованы с Python-версиях. Некоторые классы действительно пропущены за ненадобностью. Например, вместо QVariant можно использовать любой Python-объект, вместо QString простые Python-строки и тд. Но есть классы до которых просто еще не добрались разработчики. На этой странице↗️ можно посмотреть полный список нереализованных классов. При этом в разных биндингах состав может отличаться. К примеру те же QString и QVariant всё ещё доступны в PyQt4. #qt

2,260 views

Hashtags

Објавено 23 дек.

Для тех кто пропустил релиз Qt6! PySide6 уже доступен! Для старта можно взять эти странички: https://wiki.qt.io/Qt_for_Python https://doc.qt.io/qtforpython/ https://doc.qt.io/qtforpython/tutorials/index.html Там же есть ссылка на репозиторий примеров https://code.qt.io/cgit/pyside/pyside-setup.git/tree/examples #qt

1,420 views

Hashtags

Објавено 2 ное.

Модуль Qt․py это не просто текстовый модуль, его компоненты генерируются на лету в зависимости от ситуации. Поэтому ваша любимая IDE не сможет качественно сообразить автокомплиты под этот модуль. Решение здесь более чем очевидно, надо сделать stubs-файлы. Это файлы с расширением .pyi, описывающие содержимое модуля но не имеющие рабочего кода. Ну что, готовы потратить пару месяцев своей жизни чтобы описать все классы Qt и их методы? 😭 Расслабьтесь, за вас это уже сделали добрые люди. Спасибо Fredrik Averpil ! Качаем здесь ⬇️ https://github.com/fredrikaverpil/Qt.py/tree/stubs/stubs/Qt Не думаю что стоит устанавливать Qt․py из этого репозитория. Он там не обновляется. Так что забираем только файлы .pyi. За актуальность этих файлов тоже не ручаюсь, но большинство методов там имеются. Установка: 🔸 Вариант 1: - находим куда установлен сам модуль Qt․py, это будет одинокий файл который так и называется Qt․py - кидаем директорию рядом с ним (если есть доступ на запись). Должно получиться так: 📁 site-packages\ 📄 Qt.py 📁 Qt\ ... 🔸 Вариант 2 - копируем директорию Qt куда угодно - пробиваем путь к ней в настройках энвайронмента в переменную PATH так, чтобы путь был ДО директории Qt. Закинуть можно и в свою домашнюю директорию. Если скопируете сюда: ~/stubs/Qt То переменную пишем так export PATH=~/stubs:${PATH} После этого IDE должна распарсить stubs-файлы и автокомплиты появятся 😎 #qt#libs#tricks

1,210 views

Објавено 30 окт.

В прошлом посте говоря "Все вызовы теперь одинаковы" я несколько слукавил. Всё-таки есть в этом зоопарке версий некоторая несовместимость вызов которой просто так не унифицировать. Эти моменты вынесены в отдельный модуль QtCompat (compatibility). Там не так много функций но они довольно полезны. Этот модуль содержит унификаци модуля shiboken2, функций loadUi, translate и несколько переименованных функций классов или изменённую сигнатуру аргументов и возвращаемых значений. Это единственное исключение из правила когда вам потребуется где-то изменить свой код кроме импортов и этот код не похож на обычный код PySide2. Например, в PyQt4 и PySide есть метод QHeaderView.setResizeMode Для PyQt5 и PySide2 они были благополучно переименованы в QHeaderView.setSectionResizeMode Чтобы применить этот метод следует использовать такой код from Qt import QtCompath header = self.horizontalHeader() QtCompat.QHeaderView.setSectionResizeMode(header, QtWidgets.QHeaderView.Fixed) Унификация загрузки UI файлов: # PySide2 from PySide2.QtUiTools import QUiLoader loader = QUiLoader() widget = loader.load(ui_file) # PyQt5 from PyQt5 import uic widget = uic.loadUi(ui_file) # Qt.py from Qt import QtCompat widget = QtCompat.loadUi(ui_file) Хорошо что таких моментов не много и их легко запомнить. Полный список можно посмотреть в таблице. #qt#tricks

1,150 views

Hashtags

Објавено 28 окт.

Для тех кто пишет расширения на PyQt/PySide для CG-софтов. Когда я только начинал писать тулзы под Maya (тогда еще версия 2010-2011) мне приходилось ручками ставить PyQt4 под Maya. Даже написал мануалы по установке на своём сайте. Но потом стал доступен из коробки PySide и позже он обновится до PySide2. Для некоторых систем была поддержка PyQt5. И как простому разработчику поддерживать этот зоопарк? Ведь хочется чтобы тул работал на любой версии (вы тоже делали модуль что-то типа import_qt.py?😁) На помощь приходит проект Qt.py который поставил себе цель унифицировать использование Qt-биндингов вне зависимости от среды где запускается код. Те, кто давно пишут на Qt, скорее всего знают этот проект. Он стал стандартом для CG-индустрии и используется в топовых студиях и проектах. Qt․py помогает запускать один и тот же код на разных платформах с разными вариантами Qt-библиотек. Это может быть как интеграция в CG-софт, так и переносимость стендалонов между разными платформами с разными версиями Python. Я решил рассказать о некоторых особенностях работы с этой библиотекой. Сегодня о том, как установить и использовать Qt․py и что это вам даёт. Установка pip install Qt.py Чтобы начать использовать Qt․py в коде достаточно заменить импорт вашего варианта Qt-биндинга на Qt․py from [PySide|PyQt4|PySide2|PyQt5] import QtWidgets => from Qt import QtWidgets Теперь ваш код будет поддерживать любой вариант биндинга Qt в Python. При этом не потребуется использовать if-else конструкции под разные версии. Все вызовы теперь одинаковы. Всё что нужно сделать, это написать его по правилам PySide2. Именно эта версия была взята за основу. Приоритет импорта такой: 1. PySide2 2. PyQt5 3. PySide 4. PyQt4 Что именно загрузилось можно посмотреть в переменной __binding__ >>> import Qt >>> Qt.__binding__ 'PySide2' Приоритет имопрта можно изменить через переменные QT_PREFERRED_BINDING и QT_PREFERRED_BINDING_JSON. Причем под каждый проект оверрайды можно настраивать индивидеально. #qt#libs

1,190 views

Hashtags

Објавено 14 окт.

🙄Разминка для ума! Треугольник Серпинского, интересная фигура которую построить достаточно просто. Алгоритм такой: 1. создаём любые 3 точки на плоскости 2. из этих точек случайно выбираем любую, как начальную 3. случайно выбираем любую точку из этих же трёх точек как цель 4. перемещаемся в сторону цели на половину расстояния 5. повторяем бесконечно с пункта 3 Если сделать достаточно много итераций то вырисовывается интересная фигура. Треугольник, в который вписаны более мелкие треугольники. Это самый настоящий фрактал! Я собрал пример построения такой фигуры на базе Qt. 🌎 Код можно посмотреть здесь. С помощью paintEvent я рисую точки по озвученному алгоритму. Каждые 10 секунд либо по клику на виджете строится следующий треугольник. Особенности примера: 🔸 Атрибут Qt.WA_OpaquePaintEvent позволяет сохранить то, что было нарисовано в прошлой итерации. Таким образом мы видим постепенное наполнение точек а не мелькающую одну точку. 🔸QTimer позволяет создавать отложенные вызовы один раз или с повторением через интервал. 🔸QColor.fromHsv() позволяет создать рандомный но предсказуемый цвет с помощью HSV схемы. Не слишком светлый и не слишком тёмный но всегда с разный. Рандомизации подвергается только смещение по цветовому кругу (Hue), яркость (Value) и насыщенность (Saturation) можно контролировать отдельно в своих пределах или оставить статичными. Обычный рандом цвета по RGB не даёт такой предсказуемый результат. 🔸 Каждый новый цикл с новым треугольником предварительно затемняет предыдущие через этот вызов painter.fillRect(rec, QColor(0, 0, 0, 100)) То есть полупрозрачный цвет. Таким образом, чем старше треугольник, тем он темней. Если сделать виджет фулскрин, то у нас получится некий ScreenSaver))) 🔸 Да, я знаю, что рисование в Qt не самый лучший способ сделать этот пример) Скорее всего самый НЕподходящий. Попробуйте сделать тоже самое но другими средствами. #qt#source#tricks

1,230 views

Објавено 7 окт.

А вы ждёте Qt6 как жду его я? ))) Наверняка, те кто ждёт, уже в курсе, но я уточню даты релизов. - Qt 6.0 Feature freeze - 31.8.2020 - Qt 6.0 Alpha - 2.10.2020 - Qt 6.0 Beta 1 - 15.10.2020 - Qt 6.0.0 RC - 17.11.2020 - Qt 6.0.0 Final - 1.12.2020 Полный список https://wiki.qt.io/Qt_6.0_Release Между тем, библиотеки PySide3 ждать не стоит. Дело в том, что разработчики решили синхронизировать версии библиотек C++ и Qt for Python. Так что ждём сразу PySide6! #qt

1,130 views

Hashtags

12
ПретходнаСтраница 1 од 2Следна