Может ли кто-нибудь сказать мне, почему, когда я нажимаю кнопку тестирования, __get__
не называется? Я пробовал много вещей, но я не могу достичь желаемого поведения:дескрипторы Python3 не вызывают __get__ при доступе
когда
lt
илиgt
атрибута доступен значение соответствующегоQlineEdit
должен быть возвращен, если установлен флажок
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QVBoxLayout, QRadioButton, QGroupBox, QLineEdit, QCheckBox, QGridLayout, QLabel, QFrame, QPushButton
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIntValidator
from PyQt5.QtWidgets import QMainWindow
class LineDescriptor:
def __init__(self, row=1, label=None):
self.label = label
self.row = row
self.__name = None
def __get__(self, instance, owner=None):
print('get_called')
if instance is None:
print('is none')
return self
else:
private_name = '_{0}__{1}'.format(type(instance).__name__,
self.__name)
check_name = '_{0}__{1}'.format(type(instance).__name__,
self.__name)
if getattr(instance, check_name).isChecked():
return getattr(instance, private_name).text()
else:
return None
class CheckSelector(QGroupBox):
def __init__(self, name):
self.__dictionary = []
super(CheckSelector, self).__init__()
layout = QGridLayout()
layout.setAlignment(Qt.AlignTop)
name = QLabel(name)
layout.addWidget(name, 0, 0, 1, 1)
self.__check = QCheckBox()
layout.addWidget(self.__check, 0, 1, 1, 1)
self.setLayout(layout)
for name, attribute in type(self).__dict__.items():
if isinstance(attribute, LineDescriptor):
row = attribute.row
if attribute.label is not None:
label = QLabel(attribute.label)
self.layout().addWidget(label, row, 0, 1, 1)
int_validator = QIntValidator()
field = QLineEdit()
field.setValidator(int_validator)
layout.addWidget(field, row, 1, 1, 1)
private_name = '_{0}__{1}'.format(type(self).__name__, name)
setattr(attribute, '_LineDescriptor__name', name)
setattr(self, name, attribute)
setattr(self, private_name, field)
print(attribute)
print(attribute.__dict__)
class GtCheck(CheckSelector):
gt = LineDescriptor(1, '>')
class BothCheck(CheckSelector):
gt = LineDescriptor(1, '>')
lt = LineDescriptor(2, '<')
def checker():
print(test.lt)
app = QApplication(sys.argv)
win = QMainWindow()
wid = QFrame()
lay = QVBoxLayout()
test = BothCheck(name='слов')
lay.addWidget(test)
but = QPushButton()
but.clicked.connect(checker)
lay.addWidget(but)
wid.setLayout(lay)
win.setCentralWidget(wid)
win.show()
sys.exit(app.exec_())
спасибо, Kevin. > По-моему, это плохой дизайн, но это не совсем неправильно. Это действительно важно для меня: делать это определенно правильно. вещи, которую я хочу достичь в том, что: У меня есть фильтр объектов и много таких селекторов , которые я хочу ответить так: они имеют некоторый ATTRS и каждый из этой ATTRS ответить так: при создании селектора - есть одно поле, добавленное в макет селекторов для каждого attr такого рода, который у него есть. , когда attr acceded: если selectors checkbox проверял значение этого поля attr, возвращаемого. Каким образом это может быть достигнуто для правильного проектирования? –
Прошу прощения, но Qt не является моей областью знаний. Большая часть вашего комментария для меня такова. Что вы пытались сделать с этим вызовом 'setattr()'? На что вы надеетесь, что это будет достигнуто? – Kevin
Чтобы предоставить возможность esily создавать декларативные подклассы. Подкласса есть, например: класса SomeClass (CheckSelector): attr1 = LineDescriptor() attr2 = LineDescriptor() Что мне нужно: все экземпляры SomeClass имеет свойство с некоторым поведением. И некоторые шаги необходимо выполнить на этапе .__ init__ шаг для каждого из таких свойств. setattr необходимо только установить свойство в экземпляр –