Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 15, 2015 20:38:27

KrisTinka
Зарегистрирован: 2015-01-09
Сообщения: 11
Репутация: +  0  -
Профиль   Отправить e-mail  

Динамическое создание методов.

Возможно-ли динамически создать метод класса? Имена заранее известны.

    self.changeActor = [self.changeActor_0,self.changeActor_1]
        for index_actor in range(len(self.actor_classes)):
            self.connect(self.actor_class[index_actor], QtCore.SIGNAL('stateChanged(int)'), self.changeActor[index_actor])
    
    def changeActor_0(self,value):
        self.changes = True
        if value:
            actors = []
            for actor in self.actor_classes:
                if actor.keys()[0] in self.actor or actor.keys()[0] == self.actor_classes[0].keys()[0]:
                    actors.append(actor.keys()[0])
            self.actor = actors
        else:
            self.actor.remove(self.actor_classes[0].keys()[0])
        parser.set(self.user,'actors',unicode(self.actor))
        self.testCheckActor()
        printing(self.actor)
    def changeActor_1(self,value):
        self.changes = True
        if value:
            actors = []
            for actor in self.actor_classes:
                if actor.keys()[0] in self.actor or actor.keys()[0] == self.actor_classes[1].keys()[0]:
                    actors.append(actor.keys()[0])
            self.actor = actors
        else:
            self.actor.remove(self.actor_classes[1].keys()[0])
        parser.set(self.user,'actors',unicode(self.actor))
        self.testCheckActor()
        printing(self.actor)
В таком виде всё работает, хотелось бы избавится от множества def changeActor_*(self,value), количество которых превышает 200.
Python 2.7

Отредактировано KrisTinka (Янв. 15, 2015 20:41:32)

Офлайн

#2 Янв. 15, 2015 20:48:26

terabayt
От: Киев
Зарегистрирован: 2011-11-26
Сообщения: 1099
Репутация: +  103  -
Профиль   Отправить e-mail  

Динамическое создание методов.

    self.changeActor = [self.changeActor_0]*2 # 2 - количество
        for index_actor in range(len(self.actor_classes)):
            self.connect(self.actor_class[index_actor], QtCore.SIGNAL('stateChanged(int)'), self.changeActor[index_actor])
    
    def changeActor_0(self,value):
        self.changes = True
        if value:
            actors = []
            for actor in self.actor_classes:
                if actor.keys()[0] in self.actor or actor.keys()[0] == self.actor_classes[0].keys()[0]:
                    actors.append(actor.keys()[0])
            self.actor = actors
        else:
            self.actor.remove(self.actor_classes[0].keys()[0])
        parser.set(self.user,'actors',unicode(self.actor))
        self.testCheckActor()
        printing(self.actor)
а так нельзя?
        for index_actor in range(len(self.actor_classes)):
            self.connect(self.actor_class[index_actor], QtCore.SIGNAL('stateChanged(int)'), self.changeActor_0)
    
    def changeActor_0(self,value):
        self.changes = True
        if value:
            actors = []
            for actor in self.actor_classes:
                if actor.keys()[0] in self.actor or actor.keys()[0] == self.actor_classes[0].keys()[0]:
                    actors.append(actor.keys()[0])
            self.actor = actors
        else:
            self.actor.remove(self.actor_classes[0].keys()[0])
        parser.set(self.user,'actors',unicode(self.actor))
        self.testCheckActor()
        printing(self.actor)



————————————————
-*- Simple is better than complex -*-

Отредактировано terabayt (Янв. 15, 2015 20:48:51)

Офлайн

#3 Янв. 15, 2015 20:55:06

KrisTinka
Зарегистрирован: 2015-01-09
Сообщения: 11
Репутация: +  0  -
Профиль   Отправить e-mail  

Динамическое создание методов.

terabayt
а так нельзя?
Нет.
self.actor_class[index_actor]
- различные чекбоксы, в таком случае метод не узнает, от какого чекбокса был послан сигнал

Отредактировано KrisTinka (Янв. 15, 2015 20:56:07)

Офлайн

#4 Янв. 15, 2015 21:18:49

terabayt
От: Киев
Зарегистрирован: 2011-11-26
Сообщения: 1099
Репутация: +  103  -
Профиль   Отправить e-mail  

Динамическое создание методов.

ага, я не увидел self.actor_classes
можете скинуть код, нужно проверить через лямбду
я прост не могу понять откуда в def changeActor_0(self,value) берется value



————————————————
-*- Simple is better than complex -*-

Отредактировано terabayt (Янв. 15, 2015 21:35:10)

Офлайн

#5 Янв. 16, 2015 15:03:35

KrisTinka
Зарегистрирован: 2015-01-09
Сообщения: 11
Репутация: +  0  -
Профиль   Отправить e-mail  

Динамическое создание методов.

terabayt
скинуть код
Вот обрезанный рабочий вариант.
# coding=utf-8
import sys
from PyQt4 import QtCore, QtGui
class Tuner(QtGui.QWidget):
    
    def __init__(self,*args):
        QtGui.QWidget.__init__(self,*args)
        self.setWindowTitle(u'Тест')
        boxlay = QtGui.QHBoxLayout(self)
        frame = QtGui.QFrame(self)
        gridlay = QtGui.QGridLayout(frame)
        self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.MSWindowsFixedSizeDialogHint)
        
        # Базовый список словарей, загружается парсером(длина неизвестна)
        self.actor_classes = [{u'one':u'Один'}, {u'two':u'Два'}, {u'three':u'Три'}]
        
        # Текущие настройки, загружаются парсером
        self.actor = [u'one',u'three']
        
        # Списки чеков и методов(создаётся с запасом)
        self.actor_class_0 = self.actor_class_1 = self.actor_class_2 = self.actor_class_3 = None
        self.actor_class = [self.actor_class_0,self.actor_class_1,self.actor_class_2,self.actor_class_3]
        self.changeActor = [self.changeActor_0,self.changeActor_1,self.changeActor_2,self.changeActor_3]
        
        for index_actor in range(len(self.actor_class)):
            if index_actor == len(self.actor_classes): break
            # Создаём чекбокс
            self.actor_class[index_actor] = QtGui.QCheckBox(self.actor_classes[index_actor].values()[0], frame)
            if self.actor_classes[index_actor].keys()[0] in self.actor: self.actor_class[index_actor].setCheckState(QtCore.Qt.Checked)
            gridlay.addWidget(self.actor_class[index_actor],0,index_actor)
            # Посылаем сигнал
            self.connect(self.actor_class[index_actor], QtCore.SIGNAL('stateChanged(int)'), self.changeActor[index_actor])
               
        boxlay.addWidget(frame)  
        
    def changeActor_0(self,value):
        if value:
            actors = []
            for actor in self.actor_classes:
                if actor.keys()[0] in self.actor or actor.keys()[0] == self.actor_classes[0].keys()[0]:
                    actors.append(actor.keys()[0])
            self.actor = actors
        else:
            self.actor.remove(self.actor_classes[0].keys()[0])
        print self.actor
    def changeActor_1(self,value):
        if value:
            actors = []
            for actor in self.actor_classes:
                if actor.keys()[0] in self.actor or actor.keys()[0] == self.actor_classes[1].keys()[0]:
                    actors.append(actor.keys()[0])
            self.actor = actors
        else:
            self.actor.remove(self.actor_classes[1].keys()[0])
        print self.actor
    def changeActor_2(self,value):
        if value:
            actors = []
            for actor in self.actor_classes:
                if actor.keys()[0] in self.actor or actor.keys()[0] == self.actor_classes[2].keys()[0]:
                    actors.append(actor.keys()[0])
            self.actor = actors
        else:
            self.actor.remove(self.actor_classes[2].keys()[0])
        print self.actor
    def changeActor_3(self,value):pass   
        
app = QtGui.QApplication(sys.argv)
window = Tuner()
window.show()
sys.exit(app.exec_())
Кликая по чекбоксам, в консоли будет показываться, как изменяются настройки.
P.S. проблему решила, вместо отлавливания от какого чекбокса поступил сигнал, проверяю статус всех элементов
# coding=utf-8
import sys
from PyQt4 import QtCore, QtGui
new = 'some_name'
globals()[new] = 'some_value'
print some_name
class Tuner(QtGui.QWidget):
    
    def __init__(self,*args):
        QtGui.QWidget.__init__(self,*args)
        self.setWindowTitle(u'Тест')
        boxlay = QtGui.QHBoxLayout(self)
        frame = QtGui.QFrame(self)
        gridlay = QtGui.QGridLayout(frame)
        self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.MSWindowsFixedSizeDialogHint)
        
        # Базовый список словарей, загружается парсером(длина неизвестна)
        self.actor_classes = [{u'one':u'Один'}, {u'two':u'Два'}, {u'three':u'Три'}]
        
        # Текущие настройки, загружаются парсером
        self.actor = [u'one',u'three']
        
        # Списки чеков и методов(создаётся с запасом)
        self.actor_class_0 = self.actor_class_1 = self.actor_class_2 = self.actor_class_3 = None
        self.actor_class = [self.actor_class_0,self.actor_class_1,self.actor_class_2,self.actor_class_3]
        
        for index_actor in range(len(self.actor_class)):
            if index_actor == len(self.actor_classes): break
            # Создаём чекбокс
            self.actor_class[index_actor] = QtGui.QCheckBox(self.actor_classes[index_actor].values()[0], frame)
            if self.actor_classes[index_actor].keys()[0] in self.actor: self.actor_class[index_actor].setCheckState(QtCore.Qt.Checked)
            gridlay.addWidget(self.actor_class[index_actor],0,index_actor)
            # Посылаем сигнал
            self.connect(self.actor_class[index_actor], QtCore.SIGNAL('stateChanged(int)'), self.changeActor)
               
        boxlay.addWidget(frame)  
    
    def changeActor(self):
        actors = []
        for index_actor in range(len(self.actor_class)):
            if index_actor == len(self.actor_classes): break
            if self.actor_class[index_actor].isChecked():
                actors.append(self.actor_classes[index_actor].keys()[0])    
        self.actor = actors
        print self.actor
    
     
app = QtGui.QApplication(sys.argv)
window = Tuner()
window.show()
sys.exit(app.exec_())

Отредактировано KrisTinka (Янв. 16, 2015 17:06:34)

Офлайн

#6 Янв. 16, 2015 18:06:23

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2757
Репутация: +  184  -
Профиль   Отправить e-mail  

Динамическое создание методов.

> Возможно-ли динамически создать метод класса? Имена заранее известны.
Тебе нужен метод или метод класса?

> - различные чекбоксы, в таком случае метод не узнает, от какого чекбокса был послан сигнал
Создай один метод и передавай ему виджет как параметр.



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

#7 Янв. 16, 2015 18:54:30

terabayt
От: Киев
Зарегистрирован: 2011-11-26
Сообщения: 1099
Репутация: +  103  -
Профиль   Отправить e-mail  

Динамическое создание методов.

я бы ь так сделал

# coding=utf-8
import sys
from PyQt4 import QtCore, QtGui
class Tuner(QtGui.QWidget):
    
    def __init__(self,*args):
        QtGui.QWidget.__init__(self,*args)
        self.setWindowTitle(u'Тест')
        boxlay = QtGui.QHBoxLayout(self)
        frame = QtGui.QFrame(self)
        gridlay = QtGui.QGridLayout(frame)
        self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.MSWindowsFixedSizeDialogHint)
        
        # Базовый список словарей, загружается парсером(длина неизвестна)
        self.actor_classes = {1: u'Один', 2: u'Два', 3: u'Три'}
        
        # Текущие настройки, загружаются парсером
        self.actor = [1,3]
        
        for index_actor in range(1, len(self.actor_classes) + 1):
            # Создаём чекбокс
            actor_class = QtGui.QCheckBox(self.actor_classes[index_actor], frame)
            if index_actor in self.actor: actor_class.setCheckState(QtCore.Qt.Checked)
            actor_class.stateChanged.connect(lambda value, i=index_actor: self.changeActor_0(value, i))
            gridlay.addWidget(actor_class,0,index_actor)
            # Посылаем сигнал
        boxlay.addWidget(frame)  
        
    def changeActor_0(self, changed, index):
        if changed:
            self.actor.append(index)
        else:
            self.actor.remove(index)
        print self.actor   
app = QtGui.QApplication(sys.argv)
window = Tuner()
window.show()
sys.exit(app.exec_())



————————————————
-*- Simple is better than complex -*-

Офлайн

#8 Янв. 16, 2015 19:46:21

KrisTinka
Зарегистрирован: 2015-01-09
Сообщения: 11
Репутация: +  0  -
Профиль   Отправить e-mail  

Динамическое создание методов.

Rodegast
Тебе нужен метод или метод класса?
def changeActor(self) - это не метод класса Tuner? Поправьте, если ошибаюсь.
terabayt
я бы ь так сделал
Спасибо! похоже стоит глубже изучить лямбду.

Офлайн

#9 Янв. 16, 2015 22:52:26

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2757
Репутация: +  184  -
Профиль   Отправить e-mail  

Динамическое создание методов.

> Поправьте, если ошибаюсь.
changeActor это метод экземпляра класса, методы класса немного другие http://pythonz.net/references/14/



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version