События и сигналы в PyQt5
В этой части учебника PyQt5, мы изучим события и сигналы, встречающиеся в приложениях.
События
Все приложения с графическим интерфейсом являются событийно-ориентированными. События вызываются главным образом пользователем приложения. Однако, они могут быть вызваны другими средствами, к примеру подключением к Интернету, диспетчером окон или таймером. Когда мы вызываем метод exec_(), приложение входит в главный цикл. Главный цикл получает события и отправляет их объектам.
В модели событий имеются три участника:
Источник события – это объект, состояние которого меняется. Он вызывает событие. Событие инкапсулирует изменение состояния в источнике события. Цель события – это объект, которому требуется уведомление. Объект источника события делегирует задачу обработки события цели события.
Для работы с событиями PyQt5 имеет уникальный механизм сигналов и слотов. Сигналы и слоты используются для связи между объектами. Сигнал срабатывает тогда, когда происходит конкретное событие. Слот может быть любой функцией. Слот вызывается, когда срабатывает его сигнал.
Сигналы и слоты
Это простой пример, демонстрирующий сигналы и слоты в PyQt5.
В этом примере, мы показываем QtGui.QLCDNumber и QtGui.QSlider. Мы меняем число lcd путём перемещения ползунка регулятора.
Здесь мы присоединяем сигнал valueChanged слайдера к слоту display числа lcd.
Отправитель – объект, который посылает сигнал. Получатель – объект, который получает сигнал. Слот – это метод, который реагирует на сигнал.
Переопределение обработчика события
События в PyQt5 часто обрабатываются путём переопределения обработчиков.
В этом примере, мы переопределяем обработчик события keyPressEvent().
Если мы нажимаем клавишу Esc, то приложение завершается.
Отправитель события
Иногда удобно знать, какой именно виджет является отправителем сигнала. Для этого PyQt5 имеет метод sender().
В нашем примере у нас есть две кнопки. В методе buttonClicked() мы определяем, какую из кнопок мы нажали с помощью метода sender().
Обе кнопки подключаются к одному слоту.
Мы определяем источник сигнала с помощью метода sender(). В строке состояния приложения, мы показываем метку нажатой кнопки.
Отправка сигналов
Объекты, создаваемые из QObject, могут посылать сигналы. В следующем примере, мы увидим, как мы может послать пользовательский сигнал.
Мы создаём новый сигнал, названный closeApp. Этот сигнал отправляется во время события нажатия кнопки мыши. Сигнал присоединяется к слоту close() класса QMainWindow.
Сигнал создаётся с помощью pyqtSignal() как атрибут внешнего класса Communicate.
Пользовательский сигнал closeApp присоединяется к слоту close() класса QMainWindow.
Когда мы кликаем на окне курсором мыши, посылается сигнал closeApp. Приложение завершается.
В этой части руководства PyQt5, мы рассмотрели сигналы и слоты.
Для вставки кода на Python в комментарий заключайте его в теги
- Книги о Python
- GUI (графический интерфейс пользователя)
- Курсы Python
- Модули
- Новости мира Python
- NumPy
- Обработка данных
- Основы программирования
- Примеры программ
- Типы данных в Python
- Видео
- Python для Web
- Работа для Python-программистов
Как привязать нажатие на кнопки в python3 PyQt5?
Здравствуйте!
Я привязывала через setText, но мне нужно чтобы текст в Line Edit выводился каждый раз по нажатию на кнопку, а он выводится только один раз.
Делаю калькулятор.
И если можете посоветуйте документацию по PyQt.
Простой 1 комментарий
Документация для 5.12
C++ документация.
PyQt использует событийную систему. Объекты генерируют события, на которые можно подписаться и прикрепить функцию(называется слот), которая вызовется при наступлении события.
Например, кнопка QPushButton при клике на нее генерирует сигнал clicked.
def on_click(): print("clicked!") btn.clicked.connect(on_click) # btn
import sys from PyQt5.QtWidgets import QWidget, QPushButton from PyQt5.QtCore import QSize class Main(QWidget): def __init__(self): super(Main, self).__init__() self.resize(QSize(100, 100)) self.btn = QPushButton("TEST BUTTON", self) self.btn.clicked.connect(self.on_click) # соединение сигнала и слота (сигнал clicked и слот on_click) def on_click(self): print('Clicked!') if __name__ == '__main__': app = QApplication(sys.argv) ex = Main() ex.show() sys.exit(app.exec_())
Код так-то правильный, но. Во-первых, в Qt/PyQt есть и события и слоты-сигналы. Во-вторых, это два совершенно разных механизма, которые используются для разных целей.
Прошло более года, но всё же.
Искал ответ на этот же вопрос и везде вижу про btn.clicked.connect().
Одна проблема - то ли я криворукий, то ли в PyQt5 больше нет такого метода - connect() не существует и выдаёт ошибку.
import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtMultimedia import * class MainWindow(QMainWindow): def __init__(self): super().__init__() self.player = QMediaPlayer() self.song_url = QUrl("""file:///home/igor/Музыка/The_Pixes_-_Whеrе_Is_Mу_Мind.mp3""") self.create_window() def create_window(self): play_btn = QPushButton("Play", self) play_btn.move(480, 270) play_btn.clicked.connect(self.play_song()) self.setGeometry(300, 300, 960, 540) self.setMinimumSize(960, 540) self.setWindowTitle("Terpsi") self.show() def play_song(self): self.player.setMedia(QMediaContent(self.song_url)) self.player.play()
play_btn.clicked.connect(self.play_song())
в этом случае, self.play_song() будет вызван сразу, а не по клику по кнопке. Тут смысл в том, что передавать нужно сам метод, а не результат его вызова:
play_btn.clicked.connect(self.play_song)
По ходу программы будет не удобно получать доступ к кнопке play_btn, так как она определена внутри метода и будет уничтожена (только play_btn, сама кнопка останется) при завершении работы метода. Нужно выносить объявление в __init__, если, конечно, доступ к кнопке требуется в дальнейшем.
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.player = QMediaPlayer() self.song_url = QUrl("""file:///home/igor/Музыка/The_Pixes_-_Whеrе_Is_Mу_Мind.mp3""") self.play_btn = QPushButton("Play", self) self.create_window() def create_window(self): self.play_btn.move(480, 270) self.play_btn.clicked.connect(self.play_song) self.setGeometry(300, 300, 960, 540) self.setMinimumSize(960, 540) self.setWindowTitle("Terpsi") self.show() def play_song(self): self.player.setMedia(QMediaContent(self.song_url)) self.player.play()
pyqt5 button
PyQt5 supports buttons using the QPushButton class. This class is inside the PyQt5.QtWidgets group. The button can be created by calling the constructor QPushButton with the text to display as parameter.
Related course:
Introduction
To use buttons with a PyQt5 application, we need to update our import line:
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtCore import pyqtSlot
In the initUI() method, add these lines of code:
button = QPushButton('PyQt5 button', self)
button.setToolTip('This is an example button')
button.move(100,70)
QPushButton creates the widget, the first argument is text on the button.
The method setToolTip shows the message when the user points the mouse on the button.
Finally the button is moved to the coordinates x=100,y=70.
We need to create a method for a button click:
@pyqtSlot()
def on_click(self):
print('PyQt5 button click')
Add connect the method to the click with:
button.clicked.connect(self.on_click)
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
class App(QWidget):
def __init__(self):
super().__init__()
self.title = 'PyQt5 button - pythonspot.com'
self.left = 10
self.top = 10
self.width = 320
self.height = 200
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
button = QPushButton('PyQt5 button', self)
button.setToolTip('This is an example button')
button.move(100,70)
button.clicked.connect(self.on_click)
self.show()
@pyqtSlot()
def on_click(self):
print('PyQt5 button click')
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
If you are new to programming Python PyQt, I highly recommend this book.
Screenshot of PyQt5 button example above.
Qt for Python Tutorial ClickableButton
In this tutorial, we'll show you how to start handling with Qt for Python's signals and slots. Basically, this Qt feature allows your graphical widgets to communicate with other graphical widgets or your own python code. Our application will create a clickable button which will show Button clicked, Hello! in the python console each time you click it.
Let's starting by importing the necessary PySide2 classes and python sys module:
1 import sys 2 from PySide2.QtWidgets import QApplication, QPushButton
Let's also create a python function which writes the message to the console:
1 # Greetings 2 def say_hello(): 3 print("Button clicked, Hello!")
Now, as mentioned in previous examples you must create the QApplication which will run your PySide2 code:
1 # Create the Qt Application 2 app = QApplication(sys.argv)
Let's create the clickable button, a QPushButton. We pass a python string on the constructor which will label the button:
1 # Create a button 2 button = QPushButton("Click me")
Before we show the button, we must connect it to the say_hello() function that we defined previously. For now, there are two ways of doing this - by using the old style or the new style. The new style is more pythonic and that's what we'll use here. You can find more information about both approaches in Signals_and_Slots_in_PySide. The QPushButton has a predefined signal called clicked which is triggered every time that the button is pressed. We'll just connect this signal to the say_hello() function:
1 # Connect the button to the function 2 button.clicked.connect(say_hello)
Finally, we show the button and start the Qt main loop:
1 # Show the button 2 button.show() 3 # Run the main Qt loop 4 app.exec_()
Full Code
1 #!/usr/bin/python 2 # -'''- coding: utf-8 -'''- 3 4 import sys 5 from PySide2.QtWidgets import QApplication, QPushButton 6 7 def say_hello(): 8 print("Button clicked, Hello!") 9 10 # Create the Qt Application 11 app = QApplication(sys.argv) 12 # Create a button, connect it and show it 13 button = QPushButton("Click me") 14 button.clicked.connect(say_hello) 15 button.show() 16 # Run the main Qt loop 17 app.exec_()
A button to exit the application
Following the same idea, we can create a a QPushButton that closes the application when clicked.
1 from PySide2.QtWidgets import QApplication, QPushButton 2 3 if __name__ == "__main__": 4 # Create a QApplication 5 app = QApplication([]) 6 7 # Create a button 8 button = QPushButton('Exit') 9 10 # Connect the button "clicked" signal to the exit() method 11 # that finishes the QApplication 12 button.clicked.connect(app.exit) 13 14 button.show() 15 app.exec_()
Another example
Take a look of the following code, it follows the same idea previously described but interacting with other python modules
1 import sys 2 import random 3 from PySide2 import QtCore, QtWidgets, QtGui 4 5 class MyWidget(QtWidgets.QWidget): 6 def __init__(self): 7 QtWidgets.QWidget.__init__(self) 8 9 self.hello = ["Hallo Welt", "你好,世界", "Hei maailma", 10 "Hola Mundo", "Привет мир"] 11 12 self.button = QtWidgets.QPushButton("Click me!") 13 self.text = QtWidgets.QLabel("Hello World") 14 self.text.setAlignment(QtCore.Qt.AlignCenter) 15 16 self.layout = QtWidgets.QVBoxLayout() 17 self.layout.addWidget(self.text) 18 self.layout.addWidget(self.button) 19 self.setLayout(self.layout) 20 21 self.button.clicked.connect(self.magic) 22 23 24 def magic(self): 25 self.text.setText(random.choice(self.hello)) 26 27 28 if __name__ == "__main__": 29 app = QtWidgets.QApplication(sys.argv) 30 31 widget = MyWidget() 32 widget.show() 33 34 sys.exit(app.exec_())