суббота, 1 июля 2017 г.

Альтернатива bytes/str в Python 3

Наиболее значительное изменение в возможностях Python 3 это более ясное разделение между текстовыми и двоичными данными. Текст это всегда Unicode и представляется типом str, а двоичные данные представляются типом bytes. Что делает это разделение особенно ясным так это то, что str и bytes не могут смешиваться в языке Python 3 никаким явным способом. Вы не можете сцеплять их, искать один тип внутри другого, и как правило не можете передавать в функцию как аргумент один тип вместо ожидаемого другого. Это хорошая новость
Кроме того, границы между строками и байтами преодолеваются только через специальные функции, вот эту диаграмму всегда полезно держать в памяти:

Строки могут быть закодированы в байты, а байты могут быть декодированы обратно в строки.
>>> '€20'.encode('utf-8')
b'\xe2\x82\xac20'
>>> b'\xe2\x82\xac20'.decode('utf-8')
'€20'
Думайте следующим образом: строка это абстрактное представление текста. Строка содержит символы, которые являются абстрактными элементами и не надо пытаться представить их в двоичном виде. При манипулировании строками, мы остаемся в блаженное неведении о реальных процессах. Мы можем разделить и порезать их, объединить их или устроить поиск. Мы не должны волноваться о том как строки представлены внутри и сколько байт нужно для представления символов. Мы начинаем задумываться об этом когда кодируем строки в байты (например, для того чтобы послать их через канал связи) или декодируем строки из байтов.
Аргументом для кодирования и декодирования является кодировка (или кодек). Кодировка это способ представить абстрактные символы в виде двоичных данных. Существует много возможных кодировок. UTF-8, показанная здесь, это одна из них. А вот другая:
>>> '€20'.encode('iso-8859-15')
b'\xa420'
>>> b'\xa420'.decode('iso-8859-15')
'€20'
Кодирование является важной частью этого процесса перевода. Без кодирования объект байтов b'\xa420' представляет собой всего лишь кучу бит. Кодировка дает ему смысл. Используя другую кодировку, эта куча бит может иметь другое значение:
>>> b'\xa420'.decode('windows-1255')
'₪20'
Так как восемьдесят процентов потерянных усилий происходит из за неправильной кодировки, будьте осторожней;-)

понедельник, 17 апреля 2017 г.

Слоты в PyQt5


Слоты в PyQt5

Для объявления слотов в PyQt5 используется специальный декоратор.
PyQt5.QtCore.pyqtSlot ( types [, name [, result [, revision=0 ]]])
Параметры:
  • types – Типы, которые определяют сигнатуру слота C ++. Каждый тип может быть объектом типа Python или строкой, которая является именем типа C ++.
  • name – Имя слота, который будет отображаться на C ++. Если опущено, будет использовано имя украшаемого метода Python. Это может быть задано только как аргумент ключевого слова.
  • revision – ревизия слота, который экспортируется в QML. Это может быть задано только как аргумент ключевого слова.
  • result – Тип результата и может быть объектом типа Python или строкой, определяющей тип C ++. Это может быть задано только как аргумент ключевого слова.

Сигналы в PyQt5

Сигналы в PyQt5

Сигнатура сигнала в общем случае будет выглядеть следующим образом:
PyQt5.QtCore.pyqtSignal ( types [, name [, revision=0 [, arguments=[] ]]])
Создайте один или несколько перегруженных несвязанных сигналов в качестве атрибута класса.
Параметры:
  • types – Типы, определяющие сигнатуру C++ сигнала. Каждый тип может быть объектом типа Python или строкой, которая является именем типа C++. Альтернативно, каждый может быть последовательностью аргументов типа. В этом случае каждая последовательность определяет сигнатуру перегрузки другого сигнала. Первая перегрузка будет использоваться по умолчанию.
  • name – Название сигнала. Если оно опущено, используется имя атрибута класса. Это может быть задано только как аргумент ключевого слова.
  • revision – ревизия сигнала, который экспортируется в QML. Это может быть задано только как аргумент ключевого слова.
  • arguments – Последовательность имен аргументов сигнала, которые экспортируются в QML. Это может быть задано только как аргумент ключевого слова.



четверг, 2 марта 2017 г.

Виртуальная среда Python

Виртуальная среда Python 

Виртуальная среда Python (команда venv) это Виртуальная Машина (VM) или среда-песочница в которой работа выполняется независимо от среды Python. Когда вы создаете и активизируете объект venv, вы больше не имеете доступа к основной среде Python, работающей на вашей системе.

Давайте создадим venv с именем "awesome-test". Для этого вы должны выполнить следующие команды находясь в директории вашего проекта:
# python3 -m venv awesome-test
# ls
awesome-test
 
В Python 3, виртуальные возможности установлены по умолчанию. В Python 2.7 вы можете установить их командой pip install virtualenv.

Следующим шагом вы должны активировать venv. Активация venv переносит вас в независимую среду Python, в которой по умолчанию не установлено ничего:

# cd awesome-test
# ls
bin     include     lib     pyvenv.cfg
#
# source bin/activate
(awesome-test) #
(awesome-test) # echo YAY!
YAY!
 
Напоминание (awesome-test), которое появляется в приглашении командной строки говорит о том, что вы в venv. Теперь распечатайте установленные модули в вашей среде:

# pip list
pip (9.0.1)
setuptools (28.8.0)
#
 
Все модули, установленные в этой виртуальной среде так в ней останутся.
Когда вы выполнили все, что хотели, вы можете выйти (деактивировать) при помощи команды деактивации:

(awesome-test) # deactivate
#
 
Замечание: Все изменения, сделанные вами в виртуальной среде не будут потеряны. Онм все сохранятся в venv.

пятница, 6 января 2017 г.

Про PyQt5

Прошло время и многое изменилось. Теперь доступен Python 3.9, Eclipse 2021-6, Pydev 8.2.0. и пакет PyQt6-он тесно связан с оригинальным пакетом Qt v6.
Я рекомендую обновить Python на версию 3.9. С сайта Eclipse.org скачать установщик и скачать последную версию для разработчиков java с предустановленной JVM, затем войти в eclipse и загрузить PyDev через Eclipse Marketplace.
В Win 10 запустике командную строку от администратора, в ней наберите команду pip install PyQt6, PyQt6-tools. 
Затем входите в Eclipse, в меню Windows выбираете Preference и затем Pydev и interpretators -> Python.
В открывшемся диалоге надо прописать путь к программе Python. Затем нажимаете Apply and Close.
В правом верхнем углу нажмите значок Open Perspectives и в открывшемся окне выберите Pydev.
Вы можете начинать работать с Python и PyQt6 в Eclipse.

Классы PyQt5 разделены на несколько модулей, включая следующие:

  • QtCore
  • QtGui
  • QtWidgets
  • QtMultimedia
  • QtBluetooth
  • QtNetwork
  • QtPositioning
  • Enginio
  • QtWebSockets
  • QtWebKit
  • QtWebKitWidgets
  • QtXml
  • QtSvg
  • QtSql
  • QtTest
- Модуль QtCore содержит ядро с неграфической функциональностью. Этот модуль используется для работы с временем, файлами, папками, различными типами файлов, потоками, адресами URL, MIME-типами и процессами.
- QtGui содержит классы для интеграции систем окон, обработки событий, 2D-графики, базовой обработки изображений, шрифтов и текста.
- Модуль QtWidgets содержит классы, которые обеспечивают набор UI-элементов для создания классических пользовательских интерфейсов.
- QtMultimedia содержит классы для управления мультимедиа-содержимым, а также API для доступа к камере или функциональности радио.
- Модуль QtBluetooth содержит классы для поиска устройств, соединения и взаимодействия с ними.
- Модуль QtNetwork содержит классы для сетевого программирования. Эти классы облегчают работу с клиентами и серверами TCP/IP и UDP, делая сетевое программирование более легким и адаптивным.
- QtPositioning содержит классы для определения местоположения с использованием всевозможных источников, таких как спутники, Wi-Fi или текстовые файлы.
- Модуль Enginio реализует клиентскую библиотеку для организации доступа к облачным сервисам Qt – Manaded Application Runtime.
- Модуль QtWebSockets содержит классы, которые реализуют протокол WebSocket.
- QtWebKit содержит классы для реализации веб-браузера, основанного на библиотеке WebKit2.
- Модуль QtWebKitWidgets содержит классы для WebKit1, основанные на реализации веб-браузера, для использования в приложениях, базирующихся на QtWidgets.
- QtXml содержит классы для работы с XML файлами. Этот модуль предоставляет реализацию сразу для двух API: SAX и DOM.
- Модуль QtSvg содержит классы для отображения содержимого SVG-файлов. Scalable Vector Graphics (SVG) – это язык для описания двумерной графики и графических приложений в XML.
- Модуль QtSql предоставляет классы для работы с базами данных.
- QtTest содержит функции, которые дают возможность модульного тестирования PyQt-приложений.

Различия PyQt4 и PyQt5

PyQt5 не имеет обратной совместимости с PyQt4; существует несколько значительных изменений в PyQt5. Тем не менее, не так сложно приспособить старый код к новой библиотеке. Среди прочих, существуют следующие различия:
  • Модули Python были реорганизованы. Некоторые модули были исключены (QtScript), другие были разделены на субмодули (QtGui, QtWebKit).
  • Новые модули представлены в виде QtBluetooth, QtPositioning или Enginio.
  • PyQt5 поддерживает только новый стиль обработки сигналов и слотов. Вызовы вида SIGNAL() или SLOT() больше не поддерживаются.
  • PyQt5 не поддерживает части Qt API, которые помечены как устаревшие в Qt v5.0.

Рассмотрим доступ к базе данных SQLITE через модуль PyQt5 - QtSql.

Источник злесь https://www.tutorialspoint.com/pyqt/pyqt_database_handling.htm
Для начала создадим простую базу sqlite:

from PyQt5 import QtSql
from PyQt5.QtWidgets import QMessageBox, QApplication, qApp

def createDB():
   db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
   db.setDatabaseName('sports.db')
  
   if not db.open():
       QMessageBox.critical(None, qApp.tr("Cannot open database"),
         qApp.tr("Unable to establish a database connection.\n"
            "This example needs SQLite support. Please read "
            "the Qt SQL driver documentation for information "
            "how to build it.\n\n" "Click Cancel to exit."),
         QMessageBox.Cancel)
          
       return False
      
   query = QtSql.QSqlQuery()
  
   query.exec_("create table sportsmen(id int primary key, "
      "firstname varchar(20), lastname varchar(20))")
      
   query.exec_("insert into sportsmen values(101, 'Roger', 'Federer')")
   query.exec_("insert into sportsmen values(102, 'Christiano', 'Ronaldo')")
   query.exec_("insert into sportsmen values(103, 'Ussain', 'Bolt')")
   query.exec_("insert into sportsmen values(104, 'Sachin', 'Tendulkar')")
   query.exec_("insert into sportsmen values(105, 'Saina', 'Nehwal')")
   return True
  
if __name__ == '__main__':
   import sys
  
   app = QApplication(sys.argv)
   createDB()

---------------------------------------
Теперь рассмотрим программу просмотра и модификации этой базы данных.
В программе вставляем импорт:
from PyQt5 import QtSql

Создаем объект типа база данных к SQLITE:
db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
Теперь надо задать базу данных, которую собираемся обрабатывать:
db.setDatabaseName('sports.db')

В кдассе QSqlDatabase есть еще следующие методы

Методы и описание
1 setDatabaseName    Устанавливает имя базы данных
2 setHostName             Устанавливает имя хоста, на котором находится ваша база
3 setUserName             Залает имя пользователя для связи
4 setPassword              Задает пароль для связи
5 commit                     Заканчивает транзакцию, в случае успеха возвращает true
6rollback                     Откатывает назад транзакцию
7 close                          Закрывает соединение

Доступ к данным в таблице проще всего получить через определение модели данных:
model = QtSql.QSqlTableModel()
Теперь, в модели определим некоторые летали:
Имя таблицы
   model.setTable('sportsmen')
Режим внесения изменений при просмотре
   model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)
Использование метода выбора
   model.select()
Назначаем наименование столбцов таблицы
   model.setHeaderData(0, QtCore.Qt.Horizontal, "ID")
   model.setHeaderData(1, QtCore.Qt.Horizontal, "First name")
   model.setHeaderData(2, QtCore.Qt.Horizontal, "Last name")

Для визуального просмотра таблицы создаем объект view:
view = QTableView()
Класс QTableView находится в модуле PyQt5.QtWidgets. В view определяем модель и заголовок:
   view.setModel(model)
   view.setWindowTitle("title")


Затем организуется диалог вида
dlg = QDialog()
layout = QVBoxLayout()
И уже в этот layout добавляется view:
layout.addWidget(view)

-------------------------------------------------------------------------
Полный пример программы:

import sys
from PyQt5 import QtCore, QtSql, QtGui
from PyQt5.QtWidgets import QMessageBox, QApplication, QTableView, QDialog, QVBoxLayout, QPushButton, qApp

def initializeModel(model):
   model.setTable('sportsmen')
   model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)
   model.select()
   model.setHeaderData(0, QtCore.Qt.Horizontal, "ID")
   model.setHeaderData(1, QtCore.Qt.Horizontal, "First name")
   model.setHeaderData(2, QtCore.Qt.Horizontal, "Last name")
   
def createView(title, model):
   view = QTableView()
   view.setModel(model)
   view.setWindowTitle(title)
   return view
   
def addrow():
   print (model.rowCount())
   ret = model.insertRows(model.rowCount(), 1)
   print (ret)
   
def findrow(i):
   delrow = i.row()
   
if __name__ == '__main__':

   app = QApplication(sys.argv)
   db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
   db.setDatabaseName('sports.db')
   model = QtSql.QSqlTableModel()
   delrow = -1
   initializeModel(model)
   
   view1 = createView("Table Model (View 1)", model)
   view1.clicked.connect(findrow)
   
   dlg = QDialog()
   layout = QVBoxLayout()
   layout.addWidget(view1)
   
   button = QPushButton("Add a row")
   button.clicked.connect(addrow)
   layout.addWidget(button)
   
   btn1 = QPushButton("del a row")
   btn1.clicked.connect(lambda: model.removeRow(view1.currentIndex().row()))
   layout.addWidget(btn1)
   
   dlg.setLayout(layout)
   dlg.setWindowTitle("Database Demo")
   dlg.show()
   sys.exit(app.exec_())

В Pyqt5 существует три вида приложений: 
   from PyQt5.QtCore import QCoreApplication 
В нем вы строите консольные приложения;
   from PyQt5.QtGui import QGuiApplication
В нем вы строите диалоговые приложения без использования библиотеки QtWidgets;
   from PyQt5.QtWidgets  import QApplication
В нем вы строите диалоговые приложения с использованием библиотеки QtWidgets.
---
Начиная с Qt 5.5 в Python3 окружении появился отдельный модуль PyQtWebEngine вместо класса PyQt5.QtWebKit. Устанавливать его нужно отдельной командой 
pip install PyQtWebEngine  
PyQtWebEngine - это набор привязок Python для библиотек Qt WebEngine компании Qt. Привязки находятся поверх PyQt и реализованы в виде набора из трех модулей. До версии 5.12 эти привязки были частью самого PyQt.
---
Для проверки версий установленных пакетов используйте команду pip list из командной строки. Советую запускать от имени Администратора. 
Для проверки появления обновлений используйте команду pip list -o.
Для обновления модуля используйте команду pip install -U имя модуля.
 
У меня в Python3 стоят модули: 
PyQt5          5.15.1
pyqt5-tools    5.15.1.1.7.5
PyQtChart      5.15.1
PyQtWebEngine  5.15.1 
 
 
Обратите внимание -  первые три цифры версии должны совпадать.  
Для Python я использую IDE Eclipse. Скачиваю последнюю версию для разработчиков Java и устанавливаю. На компьютере стоит уже Jdk14.  Его я скачал с сайта Oracle. Запускаем Eclipse и в HELP находим Eclipse Marketplace, в строке find вводим Pydev и нажимаем значок поиска. Первая найденная строка будет Pydev, в правом нижнем углу полосы нажимаем кнопку Install. Перезапускаем Eclipse и переходим к насиройке Pydev.
 
В кнопке Windows внизу нажимаем Preferences. В открывшемся окне, в левом вертикальном списке нажимаем Pydev. Открывается список, относящийся к настройке Pydev. В этом списке выбираем строку Interpreters. Затем выбираем Python Interpreter. В верхнем окне выбираем место, где установлен Python3.
 


 
 




воскресенье, 28 августа 2016 г.

RaspberryPi3&Вокруг

Купил Raspberry Pi 3 B и к нему дисплей 5inch HDMI LCD (B). Что бы полноценно подключить дисплей много мучился. Подключил, и вот итог. Из документации следует, что если у вас дисплей с последней версией микропрограммы 2.1, то драйверов никаких не надо, он будет работать сразу с raspberian
Jessie с сайта https://www.raspberrypi.org/downloads/raspbian/. В магазине onpad.ru членораздельно ответить на вопрос какая версия не смогли. Теперь я знаю: версия 2.1.

Итак, берем microSD 16 Gb и вставляем в ПК через ридер. 
Скачиваем файл с операционнкой raspberian Jessi, разархивируем ее. Получаем файл с расширением .img.
Скачиваем приложение Win32DiskImager. Оно бесплатное. Я скачал в файле .zip чтобы не устанавливать. Запускаем программу Win32DiskImager и выбираем файл с операционкой. Программа сама найдет карту microSD. Нажимаем клавишу write. После окончания карта готова для работы с Raspberry. Но стоп!

Если сейчас начать загружаться с этой карты, то экран на дисплее будет с большой полосой справа. Поэтому Найдите на карте файл config.txt и при помощи редактора добавьте в конец файла следующие строчки:
max_usb_current=1
hdmi_group=2
hdmi_mode=1
hdmi_mode=87
hdmi_cvt 800 480 60 6 0 0 0
Вот теперь можно собирать Малинку. После старта вы сразу попадаете в удобный графический экран. Мышкой сверху выбираете иконку сети. Она просит ввести пароль доступа к Интернету. Если у вас нет доступа к Интернету по Wi-Fi, то это не ко мне. Подключается сразу. Я купил Pi3, она умеет на борте встроенный Wi-Fi.

После этого надо обновить ваш по на диске и установить программу calibrator для работы touchscreen.
Так как вы по умолчанию работаете под пользователем Pi/rasberry, то команду от администратора запускаете после команды sudo. 

Мышкой открываем терминал и вводим команду
sudo apt-get update
а затем
sudo apt-get upgrade
Мы обновили систему, теперь надо установить пакет с программой калибратором экрана
sudo apt-get install -y xinput-calibrator
После этого в терминале запускаем программу калибратор.
sudo DISPLAY=:0.0 xinput_calibrator
В ответ на это на экране поочередно появятся 4 креста. Надо быстро нажать 
на них стилусом. Как результат, программа выведет стоки калибрации. Начинаются они строкой Section и заканчиваются EndSection. Внимание: не закрывайте окно терминала. Эти строки надо выделить и выбрать в буфер.

Откройте новое окно терминала. Теперь надо создать директорию под файл конфигурации калибровки экрана.
Вводим команду
sudo mkdir /etc/X11/xorg.conf.d
Теперь в этой директории надо создать файл
sudo nano /etc/X11/xorg.conf.d/99-calibration.conf
У вас появиться пустой экран редактора. Вставьте выбранные строки из программы калибратора. Чтобы сохранить введите команду Ctrl+O и ввод. Потом Ctrl+X для выхода.
Теперь введите команду
sudo reboot
для перезагрузки и вуаля! Вы можете без мышки использовать стилус. Один порт USB свободен!

Для нормального доступа к USB устройствами с NTFS, можно ввести команду
sudo apt-get install ntfs-3g
Теперь втыкаете в PI3 устройство и работаете с ним. Кстати, блок питания я купил на 2.5 ампера, чего и всем желаю.  




 
  

среда, 10 августа 2016 г.

События и сигналы в PyQt5

События и сигналы в PyQt5

События

Все GUI приложения основаны на обработке событий. В основном события создаются пользователем приложения. Но могут создаваться и другими источниками: например интернет соединением, управлением окон или таймером. Когда мы вызываем метод приложения exec_(), приложение запускает основную цикл. Основной цикл загружает события и посылает их к объектам.
В модели событий существует три участника:
  • событие источник
  • событие объект
  • событие цель
Событие источник это объект, чей статус изменился. Этот объект генерирует события. Объект событие(Это и есть событие) включает в себя изменение статуса в объекте источнике. Цель события это объект, который хочет быть модифицированным. Источник события делегирует задачу управления любым событием цели события.
У PyQt5 уникальный механизм работы с событиями — это сигналы (signal) и слоты (slot). Сигналы и слоты используются для связи между объектами. Сигнал выпускается когда конкретное событие возникает. Слотом может быть все, что можно вызвать на языке Python. Слот вызывается когда связанный с ним сигнал появляется.

Сигналы и слоты

Это простой пример демонстрирующий сигналы и слоты в PyQt5.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

В этом примере мы связываем сигнал от QSlider к слоту в QLCDNumber. 

author: Jan Bodnar
website: zetcode.com 
last edited: January 2015
"""

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QWidget, QLCDNumber, QSlider, 
    QVBoxLayout, QApplication)


class Example(QWidget):
    
    def __init__(self):
        super().__init__()
        
        self.initUI()
        
        
    def initUI(self):
        
        lcd = QLCDNumber(self)
        sld = QSlider(Qt.Horizontal, self)

        vbox = QVBoxLayout()
        vbox.addWidget(lcd)
        vbox.addWidget(sld)

        self.setLayout(vbox)
        sld.valueChanged.connect(lcd.display)
        
        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Signal & slot')
        self.show()
        

if __name__ == '__main__':
    
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())
В примере мы выводим на экран QtGui.QLCDNumber и QtGui.QSlider. Мы изменяем число lcd перетаскивая мышкой кнопку ползунка.
sld.valueChanged.connect(lcd.display)
Здесь мы соединяем сигнал valueChanged ползунка со слотом ИЗОБРАЖЕНИЯ числа lcd.
Тот кто посылает это объект, посылающий сигнал. Получатель, это объект получающий сигнал. Слот это метод, который реагирует на сигнал.
Signal & slot Figure: Signal & slot

Переписывание обработчика событий

События в PyQt5 часто обрабатывают переделывая обработку событий.

#!/usr/bin/python3

# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

В этом примере мы переделываем обработку событий. 

author: Jan Bodnar
website: zetcode.com 
last edited: January 2015
"""

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QApplication


class Example(QWidget):
    
    def __init__(self):
        super().__init__()
        
        self.initUI()
        
        
    def initUI(self):      
        
        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Event handler')
        self.show()
        
        
    def keyPressEvent(self, e):
        
        if e.key() == Qt.Key_Escape:
            self.close()
        
        
if __name__ == '__main__':
    
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())
В нашем примере мы переписываем обработчик нажатия клавиш keyPressEvent().
def keyPressEvent(self, e):
    
    if e.key() == Qt.Key_Escape:
        self.close()
Если мы нажимаем клавишу Escape, то приложение закрывается.

Посылающий событие

Иногда очень удобно знать какое виджет послал сигнал. Для этого, PyQt5 имеет метод sender().

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

В этом примере мы определяем объект посылающий событие.

author: Jan Bodnar
website: zetcode.com 
last edited: January 2015
"""

import sys
from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication


class Example(QMainWindow):
    
    def __init__(self):
        super().__init__()
        
        self.initUI()
        
        
    def initUI(self):      

        btn1 = QPushButton("Button 1", self)
        btn1.move(30, 50)

        btn2 = QPushButton("Button 2", self)
        btn2.move(150, 50)
      
        btn1.clicked.connect(self.buttonClicked)            
        btn2.clicked.connect(self.buttonClicked)
        
        self.statusBar()
        
        self.setGeometry(300, 300, 290, 150)
        self.setWindowTitle('Event sender')
        self.show()
        
        
    def buttonClicked(self):
      
        sender = self.sender()
        self.statusBar().showMessage(sender.text() + ' was pressed')
        
        
if __name__ == '__main__':
    
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())
Мы имеем две кнопки. В методе buttonClicked() мы определяем какая кнопка была нажата при помощи метода sender().
btn1.clicked.connect(self.buttonClicked)            
btn2.clicked.connect(self.buttonClicked)
Обе кнопки присоединены к одному и тому же слоту.
def buttonClicked(self):
  
    sender = self.sender()
    self.statusBar().showMessage(sender.text() + ' was pressed')
Мы определили источник сигнала вызывая метод sender(). В строке состояния мы показали наименование нажатой кнопки.
Event sender Figure: Event sender

Создание сигналов

Объекты, порожденные от QObject могут порождать сигналы. В следующем примере мы увидим как мы можем создать пользовательский сигнал.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

В этом примере мы покажем как создать сигнал. 

author: Jan Bodnar
website: zetcode.com 
last edited: January 2015
"""

import sys
from PyQt5.QtCore import pyqtSignal, QObject
from PyQt5.QtWidgets import QMainWindow, QApplication


class Communicate(QObject):
    
    closeApp = pyqtSignal() 
    

class Example(QMainWindow):
    
    def __init__(self):
        super().__init__()
        
        self.initUI()
        
        
    def initUI(self):      

        self.c = Communicate()
        self.c.closeApp.connect(self.close)       
        
        self.setGeometry(300, 300, 290, 150)
        self.setWindowTitle('Emit signal')
        self.show()
        
        
    def mousePressEvent(self, event):
        
        self.c.closeApp.emit()
        
        
if __name__ == '__main__':
    
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())
Мы создали новый сигнал с именем closeApp. Этот сигнал инициируется во время события нажатия мыши. Этот сигнал связывается со слотом close() объекта QMainWindow.
class Communicate(QObject):
    
    closeApp = pyqtSignal()     
Сигнал создается методом pyqtSignal() как атрибут расширения класса Communicate. Этот метод принадлежит классу Qobject.
self.c = Communicate()
self.c.closeApp.connect(self.close) 
Пользовательский сигнал closeApp подключается к слоту close() сласса QMainWindow.
def mousePressEvent(self, event):
    
    self.c.closeApp.emit()
Когда мы нажимаем на окне мышкой, создается сигнал closeApp. Приложение заканчивается.

X-Plane 11, 12 - любитель, Фото любитель со стажем

Постоянные читатели

Архив блога