Форум сайта python.su
Ну все зависит от конкретной задачи, это всего лишь пример того что к-во полей может быть негораничено, и необязательно заранее знать как они будут все называться. потому как ТС слишком прямолинейно подходит к решению задачи.
[code python][/code]
Офлайн
Да, когда я увидел последнюю версию программы, то был в восторге, как оно всё работает. Удивительно.
Стал модифицировать программу, добавил кнопку копирования результата, и странное дело, вроде делал всё по образцу, но при копировании почему-то выдаёт ошибку, типа поле не найдено:
global name 'pole' is not defined
# Python 3. PyQt4 # -*- coding: utf-8 -*- import sys from PyQt4 import QtGui, QtCore sss_vivod = ("background-color: #d0f0c0; font: 10pt 'Arial black'") sss = ("background-color: #edecbe; font: 10pt") class MyTextEdit(QtGui.QLineEdit): # создаем свой класс наследуя QLineEdit def __init__(self, *args, **kwargs): super().__init__() self.poles = [] # пустой список ссылок на поля вычислений self.polesCopy = [] # пустой список ссылок на поля копирования def addPole(self, pole): self.poles.append(pole) # добавляем ссылку на поле в список print(self.poles) def addPoleCopy(self, pole): self.polesCopy.append(pole) # добавляем ссылку на поле в список def valueChange(self,*args): s=0 # по умолчанию результат = 0 for pole in self.poles: text = pole.text() if text: s+=int(text) # прошлый результат + новое значение self.setText(str(s)) def valueCopy(self,*args): if pole in self.polesCopy[0]: s = pole.text() self.copy(str(s)) class GridLayout(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.setWindowTitle('Заголовок') self.grid = QtGui.QGridLayout() # ПОЛЯ n = 6 # строк m = 2 # столбцов for i in range(n): resultPole = MyTextEdit() # поле результата resultPole.setStyleSheet(sss_vivod) butCopy = QtGui.QPushButton('Copy') resultPole.addPoleCopy(butCopy) # добавляем ссылку на поле в список butCopy.clicked.connect(resultPole.valueCopy) self.grid.addWidget(butCopy,i,n+1) self.grid.addWidget(resultPole,i,n+2) for j in range(m): sourcePole = QtGui.QLineEdit() # поле данных sourcePole.setStyleSheet(sss) self.grid.addWidget(sourcePole,i,j) resultPole.addPole(sourcePole) # добавляем ссылку на поле в список sourcePole.textChanged.connect(resultPole.valueChange) self.setLayout(self.grid) app = QtGui.QApplication(sys.argv) qb = GridLayout() qb.move(250,250) qb.show() sys.exit(app.exec_())
Офлайн
Kyrympole не определено в функции
def valueCopy(self,*args):
if pole in self.polesCopy:
s = pole.text()
self.copy(str(s))
Офлайн
Э-м-м, а это что? зачем???
if pole in self.polesCopy[0]:
resultPole.addPoleCopy(butCopy)
self.copy(str(s))
self.selectAll() self.copy()
# -*- coding: utf-8 -*- import sys from PyQt4 import QtGui, QtCore sss_vivod = ("background-color: #d0f0c0; font: 10pt 'Arial black'") sss = ("background-color: #edecbe; font: 10pt") class MyTextEdit(QtGui.QLineEdit): # создаем свой класс наследуя QLineEdit def __init__(self, *args, **kwargs): super().__init__() self.poles = [] # пустой список ссылок на поля вычислений # Это лишнее, поле копирования это self #self.polesCopy = [] # пустой список ссылок на поля копирования def addPole(self, pole): self.poles.append(pole) # добавляем ссылку на поле в список print(self.poles) # тоже лишнее #def addPoleCopy(self, pole): # self.polesCopy.append(pole) # добавляем ссылку на поле в список def valueChange(self,*args): s=0 # по умолчанию результат = 0 for pole in self.poles: text = pole.text() if text: s+=int(text) # прошлый результат + новое значение self.setText(str(s)) def valueCopy(self,*args): #тут вобще ересь ни одной правильной строчки #if pole in self.polesCopy[0]: # s = pole.text() # self.copy(str(s)) print(self.text()) # просто для проверки self.selectAll() # выделяем все self.copy() # копируем в буфер class GridLayout(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.setWindowTitle('Заголовок') self.grid = QtGui.QGridLayout() # ПОЛЯ n = 6 # строк m = 2 # столбцов for i in range(n): resultPole = MyTextEdit() # поле результата resultPole.setStyleSheet(sss_vivod) butCopy = QtGui.QPushButton('Copy') #ЗАЧЕМ тем более что всеравно добавляете кнопку а не лайнЕдит?? \ #resultPole.addPoleCopy(butCopy) # добавляем ссылку на поле в список butCopy.clicked.connect(resultPole.valueCopy) self.grid.addWidget(butCopy,i,n+1) self.grid.addWidget(resultPole,i,n+2) for j in range(m): sourcePole = QtGui.QLineEdit() # поле данных sourcePole.setStyleSheet(sss) self.grid.addWidget(sourcePole,i,j) resultPole.addPole(sourcePole) # добавляем ссылку на поле в список sourcePole.textChanged.connect(resultPole.valueChange) self.setLayout(self.grid) app = QtGui.QApplication(sys.argv) qb = GridLayout() qb.move(250,250) qb.show() sys.exit(app.exec_())
[code python][/code]
Отредактировано PEHDOM (Апрель 10, 2017 21:21:45)
Офлайн
PEHDOMМ-да, про это я что-то забыл…,
self.selectAll()
PEHDOMЯ хотел сделать отдельный список для связи результата и кнопки. Но, как вижу, работает и без этого. Вот только я не понимаю, почему оно работает.
Э-м-м, а это что? зачем???
Офлайн
Kyrymнет, *args там только потому что textChanged вместе с сигналом передает текст. его можно заменить например на text или вообще убрать если нам не нужно получать измененный текст. Когда одно из “привязаных” полей генерирует сигнал textChanged то слот valueChange проходит по списку лайнедитов из self.poles (мы ведь их туда не зря добавляли: resultPole.addPole(sourcePole)), считывает их значения, сумирует, и пишет суму в свое поле.
при изменении ячейки срабатывает valueChange, *args распаковывает 1 список и передаёт его элементы в функцию.
KyrymУ каждого виджета MyTextEdit свой “личный” список полей из которых нужно брать значения. Вы их добавляете строкой resultPole.addPole(sourcePole).
В таком случае не ясно, как программа понимает, какой именно список нужно использовать…
Kyrymпочему не связаны? А это butCopy.clicked.connect(resultPole.valueCopy). Вы связыветет клик конкретной кнопки с методом конкретного MyTextEdit-а. ТО что вы не храните ссылку на эти виджеты в виде self.name ничего не значит, обьект остаеться в памяти пока на него указывает хотябы одна сылка. Вы создаете виджет, вы помещаетет его на форму, вы упаковываетет его в грид. Грид хранит ссылку на виджет, родитель хранит сылку на виджет. Виджет остаеться в памяти , коннекты работают.
А вот кнопки никак не связаны с результатами. В общем не понятно.
[code python][/code]
Офлайн
Можно сделать так, получается круто:
def valueChange(self,*args): s=0 # по умолчанию результат = 0 a = self.poles[0].text() b = self.poles[1].text() c = self.poles[2].text() a=int(a) if a else 0 b=int(b) if b else 0 c=int(c) if c else 0 s = a*b+c self.setText(str(s))
Отредактировано Kyrym (Апрель 11, 2017 11:32:28)
Офлайн
KyrymНу дальше все ограничено только вашей фантазией, хотя у вас много однотипных операций, и я бы поместил их в цикл, а то у вас китайский код получается.
Можно сделать так, получается круто:
def valueChange(self,*args): s=0 # по умолчанию результат = 0 res = list() for item in self.poles: res.append(int(item.text())) if item.text() else res.append(0) s = res[0]*res[1]+res[2] self.setText(str(s))
[code python][/code]
Отредактировано PEHDOM (Апрель 11, 2017 12:38:15)
Офлайн
PEHDOMК сожалению, моя фантазия ограничена моими знаниями…
Ну дальше все ограничено только вашей фантазией
class Ost(QtGui.QPushButton): # создаем свой класс наследуя ... def __init__(self, *args, **kwargs): super().__init__() self.cells = [] # пустой список ссылок на поля вычислений ... name_ost = [11,22,33] ... class GridLayout(QtGui.QWidget): ... for i, name in enumerate(name_ost): button_ost_open = Ost(name)
Отредактировано Kyrym (Апрель 11, 2017 16:24:07)
Офлайн
class Ost(QtGui.QPushButton): # создаем свой класс наследуя QLabel def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs)
Kyrymв смысле? какой “этот метод”
А этот “метод” дружит с enumerate? Или нет?
[code python][/code]
Отредактировано PEHDOM (Апрель 11, 2017 16:07:45)
Офлайн