Уведомления

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

#1 Апрель 20, 2017 15:00:22

MrViktor
Зарегистрирован: 2017-03-09
Сообщения: 83
Репутация: +  8  -
Профиль   Отправить e-mail  

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

Kyrym
Window.in_ch_f(self,a)
self применяется и к методам, то есть если метод а экземпляра класса вызывает метод в этого же экземпляра то нужно писать так
self.in_ch_f(self,a)
Возможно еще что-то упустил (бегло код посмотрел), со временем проблема.

Отредактировано MrViktor (Апрель 20, 2017 15:26:03)

Офлайн

#2 Апрель 20, 2017 16:00:07

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

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

Хм… вместо Window.in_ch_f(self,a) пишу self.in_ch_f(self,a) и вижу:

TypeError: in_ch_f() takes 2 positional arguments but 3 were given
Видимо, надо ещё что-то менять.

Офлайн

#3 Апрель 20, 2017 17:10:33

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

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

Kyrym
Хм… вместо Window.in_ch_f(self,a) пишу self.in_ch_f(self,a) и вижу:
вы можете вместо Window.in_ch_f(self,a) писать self.in_ch_f(a)
Вообще вы вроде начали понимать, но надобы еще потренироваться.
Например у вас есть метод def in_ch_f(self,x):, если вам self.x нужен исключительно для проверки\преобразования то можно сделать чтобы функция сразу возвращала нужное значение, без присваивания времменой переменной:
 # -*- coding: utf-8 -*-
import sys
from PyQt4 import QtGui, QtCore
# ЦВЕТА ПОЛЕЙ
sss_vivod = ("background-color: #456173; color: #f2f2f0; font: 12pt 'Courier New'")
# ДАННЫЕ
# ГРАФИКА
class Window(QtGui.QWidget): # Класс Window  наследует класс QWidget
    def __init__(self, parent=None, *args, **kwargs): # Создаёт конструктор класса, parent - ссылка на родительский эл-т
        QtGui.QWidget.__init__(self, parent)
        self.setMinimumSize(200, 200) # Ширина и высота окна
        self.resize(200, 200) # шир / выс окна
        self.setWindowTitle('Исключения') # Заголовок
        self.setWindowIcon(QtGui.QIcon('icon.png')) # Иконка
        # БЛОК РАЗМЕТКИ
        self.vbox_os = QtGui.QVBoxLayout()
        # ---
        self.pole = QtGui.QLineEdit()
        self.pole.setStyleSheet(sss_vivod)
        self.vbox_os.addWidget(self.pole)
        # ---
        self.pole_2 = QtGui.QLineEdit()
        self.pole_2.setStyleSheet(sss_vivod)
        self.vbox_os.addWidget(self.pole_2)
        # ---
        self.btn = QtGui.QPushButton('Выполнить')
        self.btn.clicked.connect(self.on_start)
        self.vbox_os.addWidget(self.btn)
        # ---
        self.pole_vivod = QtGui.QTextEdit('')
        self.pole_vivod.setStyleSheet(sss_vivod)
        self.vbox_os.addWidget(self.pole_vivod)
        # ---
        self.setLayout(self.vbox_os) # установка рабочей области
    # ЛОГИКА
    def on_start(self, x=None):
        def ap(i):
            data.append(i)
        data = []
        self.pole_vivod.setText('')
        a = self.pole.text()
        print('on_start до функции, a =',a)
        a = self.in_ch_f(a)  # Да, можно вот так
        print('on_start после функции, a =',a)
        ap(a)
        print('-'*50)
        b = self.pole_2.text()  # Да, можно вот так
        print('on_start до функции, b =',b)
        b = self.in_ch_f(b)
        print('on_start после функции, b =',b)
        ap(b)
        print('='*50)
        for i in data:
            self.pole_vivod.append(str(i))
    def in_ch_f(self,x):  # Наш метод возавращает результат
        try:
            x = float(x)
            print('try, x =',x)
        except (TypeError, ValueError):
            print('except, x =',x)
            x = 0
        return x
# КОНЕЦ
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = Window() # создаёт экземпляр окна из класса
    window.show() # запускает окно
    sys.exit(app.exec_())
или даже так:
 # -*- coding: utf-8 -*-
import sys
from PyQt4 import QtGui, QtCore
# ЦВЕТА ПОЛЕЙ
sss_vivod = ("background-color: #456173; color: #f2f2f0; font: 12pt 'Courier New'")
# ДАННЫЕ
# ГРАФИКА
class Window(QtGui.QWidget): # Класс Window  наследует класс QWidget
    def __init__(self, parent=None, *args, **kwargs): # Создаёт конструктор класса, parent - ссылка на родительский эл-т
        QtGui.QWidget.__init__(self, parent)
        self.setMinimumSize(200, 200) # Ширина и высота окна
        self.resize(200, 200) # шир / выс окна
        self.setWindowTitle('Исключения') # Заголовок
        self.setWindowIcon(QtGui.QIcon('icon.png')) # Иконка
        # БЛОК РАЗМЕТКИ
        self.vbox_os = QtGui.QVBoxLayout()
        # ---
        self.pole = QtGui.QLineEdit()
        self.pole.setStyleSheet(sss_vivod)
        self.vbox_os.addWidget(self.pole)
        # ---
        self.pole_2 = QtGui.QLineEdit()
        self.pole_2.setStyleSheet(sss_vivod)
        self.vbox_os.addWidget(self.pole_2)
        # ---
        self.btn = QtGui.QPushButton('Выполнить')
        self.btn.clicked.connect(self.on_start)
        self.vbox_os.addWidget(self.btn)
        # ---
        self.pole_vivod = QtGui.QTextEdit('')
        self.pole_vivod.setStyleSheet(sss_vivod)
        self.vbox_os.addWidget(self.pole_vivod)
        # ---
        self.setLayout(self.vbox_os) # установка рабочей области
    # ЛОГИКА
    def on_start(self, x=None):
        def ap(i):
            data.append(i)
        data = []
        self.pole_vivod.setText('')
        a = self.pole.text()
        print('on_start до функции, a =',a)
        a = Window.in_ch_f(a)  # вызываем  in_ch_f через класс 
        print('on_start после функции, a =',a)
        ap(a)
        print('-'*50)
        b = self.pole_2.text()
        print('on_start до функции, b =',b)
        b = self.in_ch_f(b)   # вызываем  in_ch_f через экземпляр
        print('on_start после функции, b =',b)
        ap(b)
        print('='*50)
        for i in data:
            self.pole_vivod.append(str(i))
    @staticmethod    #декоратор указывающий на то  что  in_ch_f статический метод
    def in_ch_f(x):   # Обратите внимание self отсутвует как аргумент
        try:
            x = float(x)
            print('try, x =',x)
        except (TypeError, ValueError):
            print('except, x =',x)
            x = 0
        return x    # возвращаем значение
# КОНЕЦ
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = Window() # создаёт экземпляр окна из класса
    window.show() # запускает окно
    sys.exit(app.exec_())

во втором случае у нас появился декоратор @staticmethod , это означает сто следующая за декоратором функция статичный метод.
В статичные методы, в отличие, скажем, от обычных или от classmethod(), не передаётся первый аргумент неявным образом. Тоесть по сути это простая функция внутри класса. Вызывается как через класс: a = Window.in_ch_f(a) , так и через экземпляр: b = self.in_ch_f(b), при этом данные экземпляра игнорируются, а принимаются во внимание только данные его класса.
Статические методы можно вызывать не создавая экземпляр классса.

Kyrym
Суть в том, что ссылаясь a = self.x и b = self.x, я получаю разные self.x
не совсем просто перед тем как получить self.x вы в методе in_ch_f меняете его значение.
ну и в except: надо бы указывать тип исключения



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

Отредактировано PEHDOM (Апрель 20, 2017 17:24:07)

Офлайн

#4 Апрель 20, 2017 17:40:06

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

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

Получилось компактнее, что радует.

Офлайн

#5 Дек. 15, 2017 19:33:27

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

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

Решил писать в свою тему.
Есть код:

 # Python 3
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import (QWidget, qApp, QAction, QApplication, QHBoxLayout, QVBoxLayout,
                         QGridLayout, QLabel, QLineEdit, QTextEdit, QPushButton, QComboBox,
                         QCheckBox, QRadioButton, QFrame, QScrollArea, QTabWidget, QSizePolicy,                         
                          QBrush, QColor)
from PyQt4.QtGui import QIcon, QPixmap, QPalette, QTextCursor
# ГРАФИКА
class Window(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.resize(300, 100) # шир / выс окна
        self.setWindowTitle('несущ') # Заголовок
        grid = QGridLayout()
        grid.setSpacing(5)
        # --- ---
        self.columnCount = 4
        self.lines = [None for i in range(self.columnCount)]
        #lst_on_start = ['self.on_start'+str(i) for i in range(columnCount)]
        #print('lst_on_start =',lst_on_start)
        for col in range(self.columnCount):
            line = QLineEdit()
            self.lines[col] = line
            grid.addWidget(line,0,col+1)
            self.lines[col].textChanged.connect(self.on_start)
            #self.lines[col].textChanged.connect(lst_on_start[col])
        # --- ---
        self.setLayout(grid)
    def on_start(self):
        print('1')
        lst_data = []
        for i in range(self.columnCount):
            lst_data.append(self.lines[i].text())
        print('lst_data =',lst_data)
# КОНЕЦ
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.move(40, 20) # сдвиг окна от верхнего левого угла экрана    
    window.show()
    sys.exit(app.exec_())
1 строка, 4 столбца. 1 функция ловит изменения текста в 4х ЛайнЭдитах.
В результате получим список вида:
 lst_data = ['4', '', '16', '']
Таки образом я могу собрать с полей весь текст , который там есть и обработать его. Однако меня интересует такой вопрос: как понять, какое поле заполнялось последним?
Может ли сигнал textChanged передавать информацию об имени текстового поля (либо его индексе) в функцию on_start?
Если заполнять одно поле, то его “индекс” находится просто, а если появляется второе заполненое поле, то всё… не знаю.

Отредактировано Kyrym (Дек. 15, 2017 19:35:23)

Офлайн

#6 Дек. 15, 2017 19:40:14

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

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

qlineedit.textChanged передает текст в аргументах
RTFM
https://pythonworld.ru/gui/pyqt5-widgets2.html

Офлайн

#7 Дек. 15, 2017 20:48:14

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

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

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

А сам сигнал textChanged не может передать некую заданную информацию, номер колонки в данном случае?

Пока так:

 # Python 3
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import (QWidget, qApp, QAction, QApplication, QHBoxLayout, QVBoxLayout,
                         QGridLayout, QLabel, QLineEdit, QTextEdit, QPushButton, QComboBox,
                         QCheckBox, QRadioButton, QFrame, QScrollArea, QTabWidget, QSizePolicy,                         
                          QBrush, QColor)
from PyQt4.QtGui import QIcon, QPixmap, QPalette, QTextCursor
# ГРАФИКА
class Window(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.resize(300, 100) # шир / выс окна
        self.setWindowTitle('несущ') # Заголовок
        grid = QGridLayout()
        grid.setSpacing(5)
        # --- ---
        self.columnCount = 4
        self.lines = [None for i in range(self.columnCount)]
        #lst_on_start = ['self.on_start'+str(i) for i in range(columnCount)]
        #print('lst_on_start =',lst_on_start)
        for col in range(self.columnCount):
            line = QLineEdit()
            self.lines[col] = line
            grid.addWidget(line,0,col+1)
            self.lines[col].textChanged.connect(self.on_start)
            #self.lines[col].textChanged.connect(lst_on_start[col])
        # --- ---
        self.setLayout(grid)
    def on_start(self, text):
        print('1')
        lst_data = []
        for i in range(self.columnCount):
            lst_data.append(self.lines[i].text())
        col_index = lst_data.index(text)
        print('lst_data =',lst_data)
        print('Столбец №',col_index)
# КОНЕЦ
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.move(40, 20) # сдвиг окна от верхнего левого угла экрана    
    window.show()
    sys.exit(app.exec_())

Отредактировано Kyrym (Дек. 15, 2017 20:51:03)

Офлайн

#8 Дек. 15, 2017 23:49:24

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

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

Kyrym
А сам сигнал textChanged не может передать некую заданную информацию, номер колонки в данном случае?
можно создать свой сигнал, котороый будет передавать все что угодно, хоть номкр колонки, хоть черта лысого..



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

Офлайн

#9 Дек. 16, 2017 09:02:09

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

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

PEHDOM
можно создать свой сигнал
Свои элементы создавать сложно (для меня), потом оказывается, что нужно многое предусмотреть.

Мне понравился вариант vic57. Переделал его код под свою программу:
 # Python 3
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import (QWidget, qApp, QAction, QApplication, QHBoxLayout, QVBoxLayout,
                         QGridLayout, QLabel, QLineEdit, QTextEdit, QPushButton, QComboBox,
                         QCheckBox, QRadioButton, QFrame, QScrollArea, QTabWidget, QSizePolicy,                         
                          QBrush, QColor)
from PyQt4.QtGui import QIcon, QPixmap, QPalette, QTextCursor
# ГРАФИКА
class Window(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.resize(300, 100) # шир / выс окна
        self.setWindowTitle('несущ') # Заголовок
        grid = QGridLayout()
        grid.setSpacing(5)
        # --- ---
        self.columnCount = 4
        self.lst_obj_name = ['line' + str(i) for i in range(self.columnCount)]
        self.lines = [None for i in range(self.columnCount)]
        for col in range(self.columnCount):
            line = QLineEdit()
            line.setObjectName('line' + str(col))
            self.lines[col] = line
            self.lines[col].textChanged.connect(self.on_start)
            grid.addWidget(line,0,col)
        # --- ---
        self.setLayout(grid)
    def on_start(self):
        print('press',self.sender().objectName(),self.sender().text())
        col_index = self.lst_obj_name.index(self.sender().objectName())
        print('Столбец №',col_index)
        
# КОНЕЦ
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.move(40, 20) # сдвиг окна от верхнего левого угла экрана    
    window.show()
    sys.exit(app.exec_())
У меня было плохо то, что если в столбцы вводить одинаковый текст, то программа будет выдавать неверный результат.

Отредактировано Kyrym (Дек. 16, 2017 15:32:23)

Офлайн

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

Board footer

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

Powered by DjangoBB

Lo-Fi Version