Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » GUI
  • » PyQt4 | Как в функциях ссылаться на несуществующие элементы? + Разбор self'a [RSS Feed]

#1 Март 31, 2017 09:14:35

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

PyQt4 | Как в функциях ссылаться на несуществующие элементы? + Разбор self'a

Ну все зависит от конкретной задачи, это всего лишь пример того что к-во полей может быть негораничено, и необязательно заранее знать как они будут все называться. потому как ТС слишком прямолинейно подходит к решению задачи.



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Офлайн

#2 Апрель 10, 2017 15:23:52

Kyrym
Зарегистрирован: 2016-12-28
Сообщения: 225
Репутация: +  3  -
Профиль   Отправить e-mail  

PyQt4 | Как в функциях ссылаться на несуществующие элементы? + Разбор self'a

Да, когда я увидел последнюю версию программы, то был в восторге, как оно всё работает. Удивительно.
Стал модифицировать программу, добавил кнопку копирования результата, и странное дело, вроде делал всё по образцу, но при копировании почему-то выдаёт ошибку, типа поле не найдено:

 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_())

Офлайн

#3 Апрель 10, 2017 18:08:41

vic57
Зарегистрирован: 2015-07-07
Сообщения: 908
Репутация: +  127  -
Профиль   Отправить e-mail  

PyQt4 | Как в функциях ссылаться на несуществующие элементы? + Разбор self'a

Kyrym
def valueCopy(self,*args):
if pole in self.polesCopy:
s = pole.text()
self.copy(str(s))
pole не определено в функции

Офлайн

#4 Апрель 10, 2017 21:09:16

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

PyQt4 | Как в функциях ссылаться на несуществующие элементы? + Разбор self'a

Э-м-м, а это что? зачем???

 if pole in self.polesCopy[0]:
+ строка
 resultPole.addPoleCopy(butCopy)
зачем вы туда передаете кнопку?
зачем вам вообще self.polesCopy = ведь у вас resultPole и так есть, вы из него вызываете метод valueCopy(). Класс MyTextEdit это полноценный QLineEdit, со всеми атрибутами и свойствами, к которому добавили пару методов и атрибутов.
+
 self.copy(str(s))
QLineEdit.copy() работает не так, Она не принимает параметры, а просто копирует выделеный текст в лайнЕдите в буфер. Если хотите скопировать содержимое в буфер, его нужно сначала выделить, вот так:
         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)

Офлайн

#5 Апрель 11, 2017 08:45:12

Kyrym
Зарегистрирован: 2016-12-28
Сообщения: 225
Репутация: +  3  -
Профиль   Отправить e-mail  

PyQt4 | Как в функциях ссылаться на несуществующие элементы? + Разбор self'a

PEHDOM
self.selectAll()
М-да, про это я что-то забыл…,
PEHDOM
Э-м-м, а это что? зачем???
Я хотел сделать отдельный список для связи результата и кнопки. Но, как вижу, работает и без этого. Вот только я не понимаю, почему оно работает.
Если смотреть на суммирование, то схема вроде такая:
1) получили список всех полей, со связанными по каждой строке ячейками
2) при изменении ячейки срабатывает valueChange, *args распаковывает 1 список и передаёт его элементы в функцию. Каждое поле из списка выдаёт своё значение, складывается и выводится в ячейку результата. Вообще я думал, что *args распаковывает все списки, и все результаты каждый раз пересчитываются. Но print показал, что это не так. В таком случае не ясно, как программа понимает, какой именно список нужно использовать…

При расчёте суммы ячейка результата связана со строкой через список. А вот кнопки никак не связаны с результатами. В общем не понятно.

Офлайн

#6 Апрель 11, 2017 09:57:54

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

PyQt4 | Как в функциях ссылаться на несуществующие элементы? + Разбор self'a

Kyrym
при изменении ячейки срабатывает valueChange, *args распаковывает 1 список и передаёт его элементы в функцию.
нет, *args там только потому что textChanged вместе с сигналом передает текст. его можно заменить например на text или вообще убрать если нам не нужно получать измененный текст. Когда одно из “привязаных” полей генерирует сигнал textChanged то слот valueChange проходит по списку лайнедитов из self.poles (мы ведь их туда не зря добавляли: resultPole.addPole(sourcePole)), считывает их значения, сумирует, и пишет суму в свое поле.
Kyrym
В таком случае не ясно, как программа понимает, какой именно список нужно использовать…
У каждого виджета MyTextEdit свой “личный” список полей из которых нужно брать значения. Вы их добавляете строкой resultPole.addPole(sourcePole).
Kyrym
А вот кнопки никак не связаны с результатами. В общем не понятно.
почему не связаны? А это butCopy.clicked.connect(resultPole.valueCopy). Вы связыветет клик конкретной кнопки с методом конкретного MyTextEdit-а. ТО что вы не храните ссылку на эти виджеты в виде self.name ничего не значит, обьект остаеться в памяти пока на него указывает хотябы одна сылка. Вы создаете виджет, вы помещаетет его на форму, вы упаковываетет его в грид. Грид хранит ссылку на виджет, родитель хранит сылку на виджет. Виджет остаеться в памяти , коннекты работают.



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Офлайн

#7 Апрель 11, 2017 11:29:04

Kyrym
Зарегистрирован: 2016-12-28
Сообщения: 225
Репутация: +  3  -
Профиль   Отправить e-mail  

PyQt4 | Как в функциях ссылаться на несуществующие элементы? + Разбор self'a

Можно сделать так, получается круто:

     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)

Офлайн

#8 Апрель 11, 2017 12:38:00

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

PyQt4 | Как в функциях ссылаться на несуществующие элементы? + Разбор self'a

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)

Офлайн

#9 Апрель 11, 2017 15:49:00

Kyrym
Зарегистрирован: 2016-12-28
Сообщения: 225
Репутация: +  3  -
Профиль   Отправить e-mail  

PyQt4 | Как в функциях ссылаться на несуществующие элементы? + Разбор self'a

PEHDOM
Ну дальше все ограничено только вашей фантазией
К сожалению, моя фантазия ограничена моими знаниями…

1) А этот “метод” дружит с enumerate? Или нет?

 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)
На выходе я получаю кнопки без текста…
А если я создаю кнопки внутри класса GridLayout, без class Ost, то кнопкам имена назначаются. Подозреваю, что в класс Ost надо передать какую-то информацию, но какую?

2) И эти имена объектов “<PyQt4.QtGui.QLineEdit object at 0x00000000038A0C18>” постоянные? Можно ли на них ссылаться? Можно ли по названию удалить некоторые поля из общей сетки и вставить (вставить, понятное дело, можно) на их позиции другие элементы? Или по имени для одной ячейки (из всей сетки) сделать проверку вводимых значений? Вопрос в том, реально ли такое?

3) И ещё меня интересует вопрос. Вообще я хочу сделать сетку (30х7, где 30 - это строки), столбцы которой будут лайнэдитами, кнопками, раскрывающимися списками. Отдельные ячейки с проверкой вводимых значений. Как думаете, стоит ли мне пытаться решить такую задачу последней методикой? Может лучше вернуться к начальному варианту с индексами из стр. 1 поста 4, или вообще всё руками прописать? Руками бы я уже сделал, но хотелось сделать правильно - технологично! ))

Отредактировано Kyrym (Апрель 11, 2017 16:24:07)

Офлайн

#10 Апрель 11, 2017 16:05:19

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

PyQt4 | Как в функциях ссылаться на несуществующие элементы? + Разбор self'a

 class Ost(QtGui.QPushButton): # создаем свой класс наследуя QLabel                                
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
метод super().__init__() вызывает конструктор класса родителя, соответственно ему нужно передать все атрибуты что вы передали при создании инстанса вашего класса.

Kyrym
А этот “метод” дружит с enumerate? Или нет?
в смысле? какой “этот метод”



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Апрель 11, 2017 16:07:45)

Офлайн

  • Начало
  • » GUI
  • » PyQt4 | Как в функциях ссылаться на несуществующие элементы? + Разбор self'a[RSS Feed]

Board footer

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

Powered by DjangoBB

Lo-Fi Version