Установить свойства виджета в 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
#ACM/USDT analysis :
#ACM is currently in a correction phase and is expected to retrace to test the 200 EMA before resuming its bearish momentum. However, the current level presents a good opportunity for long trade.
TF : 4H
Entry : $1.075
Target : $1.193
SL : $0.994
#ACM/USDT analysis :
#ACM is currently in a downtrend, with the price consistently trading below the 200 exponential moving average (EMA). Recent price action shows a rejection from the 200 EMA, suggesting a continuation of the downward momentum. As a result, it is expected that the price will decline further and test previous lows.
TF : 1D
Entry : $1.520
Target : $1.235
SL : $1.690
#ACM/USDT analysis :
#ACM is in a downtrend, trading below the 200 EMA. The price is currently retracing back to the 200 EMA and a resistance zone, and it is expected to decline from this point, continuing its bearish momentum to test lower levels. It is advisable to wait for a pullback for a short entry.
TF : 1H
Entry : $1.535
Target : $1.478
SL : $1.567
#ACM👈
Call given here
Hit 1667
Target 1 done ✅
14% profit
If you invested 1 btc it's now 1.14 btc now 🤑🤑
Signal before pump @ low level
Always trade with us for max profit 😊🤑💃
We are best pump tracker 🤑
#ACM#站免
ACM 五周年,站免两周。
Dear @everyone
We are absolutely thrilled to announce that we are celebrating the 5th anniversary of our beloved platform dedicated to the mesmerizing world of Asian cinema! 🥳🍾
It feels like just yesterday that we embarked on this incredible journey, passionate about bringing you the best of Asian cinema. Over the past five years, we've delved deep into the heart of cinematic artistry, exploring the rich tapestry of stories, cultures, and talents that make Asian cinema truly exceptional.
One of our core missions has always been to spread our love for Asian cinema around the globe and are very proud of what we have been able to accomplish so far. We've had the privilege of showcasing masterpieces, hidden gems, and emerging talents from across Asia. From the heartwarming dramas to the pulse-pounding action, the thought-provoking indie films to the visually stunning blockbusters, every frame has been a celebration of the cinematic excellence that defines Asian cinema.
To mark this momentous occasion, we have activated global FreeLeech (FL) for the next 2 weeks so you can finally download all those films you have bookmarked since our last global FL :). This celebration is not just about looking back but also about looking forward to the exciting cinematic adventures that await us.
None of this would have been possible without the unwavering support of our dedicated community. To each and every one of you who has shared their love for Asian cinema, contributed insightful discussions, and made this platform a vibrant hub – THANK YOU! Your enthusiasm fuels our passion, and we are incredibly grateful for your ongoing support.
As we raise a virtual toast to the past five years, we eagerly look forward to the next chapter. With your continued support, we are confident that the future holds even more exciting discoveries, cinematic treasures, and shared moments of joy.
Thank you for being a part of our cinematic journey. Here's to five years of Asian cinema magic, and to many more to come!
Cheers to the love of film! 🎉🎬✨
Yours,
AsianCinema Team