Python,装饰函数中引用类实例/方法

标签 python python-3.x pyqt pyqt5 python-decorators

我很难找到一种在装饰器函数中引用类实例的方法。

import json
import time
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from main_UI import Ui_ApplicationWindow
from slack import RTMClient

class WorkerThread(QThread):
  finished = pyqtSignal(str)   

  def __init__(self):
    QThread.__init__(self)  
    self.rtm_client = RTMClient(token="xoxp...") 

  def run(self):     
    self.rtm_client.start()

  @RTMClient.run_on(event="message")
  def say_hello(**payload):
    data = payload['data']
    if (len(data) != 0):
      if "text" in data:          
        text = data['text']         
        self.finished.emit(str(text))  


class ApplicationWindow(QMainWindow):

  def __init__(self):
    super(ApplicationWindow, self).__init__()
    self.ui = Ui_ApplicationWindow()
    self.ui.setupUi(self)   
    self.ui.pushButton.clicked.connect(self.start_rtm)      

  def start_rtm(self):
    self.thread = WorkerThread()
    self.thread.finished.connect(self.update)
    self.thread.start()

  @pyqtSlot(str)
  def update(self, data):
    self.ui.label.setText(data)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWindow = ApplicationWindow()
    myWindow.show()
    app.exec_()

因此,在 say_hello 中,由于它不能将 self 作为参数,所以我无法使用 self.finished.emit(text) 位于函数末尾。

如何在 say_hello 中使用 self 引用类实例/函数?

最佳答案

不,你不能。而不是使用@RTMClient.run_on()装饰器,使用RTMClient.on()函数来注册它。

import threading
import asyncio

from slack import RTMClient

from PyQt5 import QtCore, QtWidgets


class SlackClient(QtCore.QObject):
    textChanged = QtCore.pyqtSignal(str)

    def start(self):
        RTMClient.on(event="message", callback=self.say_hello)
        threading.Thread(target=self._start_loop, daemon=True).start()

    def _start_loop(self):
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        slack_token = "xoxb-...."
        rtm_client = RTMClient(token=slack_token)
        rtm_client.start()

    def say_hello(self, **payload):
        data = payload["data"]
        if data:
            if "text" in data:
                text = data["text"]
                self.textChanged.emit(text)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)

    client = SlackClient()

    button = QtWidgets.QPushButton("Start")
    textedit = QtWidgets.QPlainTextEdit()

    button.clicked.connect(client.start)
    client.textChanged.connect(textedit.appendPlainText)

    w = QtWidgets.QWidget()
    lay = QtWidgets.QVBoxLayout(w)
    lay.addWidget(button)
    lay.addWidget(textedit)
    w.show()

    sys.exit(app.exec_())

更新:

import sys
import threading
import asyncio

from slack import RTMClient

from PyQt5 import QtCore, QtWidgets
from main_UI import Ui_ApplicationWindow


class SlackClient(QtCore.QObject):
    textChanged = QtCore.pyqtSignal(str)

    def start(self):
        RTMClient.on(event="message", callback=self.say_hello)
        threading.Thread(target=self._start_loop, daemon=True).start()

    def _start_loop(self):
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        slack_token = "xoxb-...."
        rtm_client = RTMClient(token=slack_token)
        rtm_client.start()

    def say_hello(self, **payload):
        data = payload["data"]
        if data:
            if "text" in data:
                text = data["text"]
                self.textChanged.emit(text)


class ApplicationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(ApplicationWindow, self).__init__()
        self.ui = Ui_ApplicationWindow()
        self.ui.setupUi(self)

        self.client = SlackClient()
        # connections
        self.ui.pushButton.clicked.connect(self.client.start)
        self.client.textChanged.connect(self.ui.label.setText)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    myWindow = ApplicationWindow()
    myWindow.show()
    sys.exit(app.exec_())

关于Python,装饰函数中引用类实例/方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58244088/

相关文章:

python - Python multiply() 和 prod() 的错误结果

python - 返回可以关闭循环吗? ( python / Django )

Python Dropbox API v2 : error when passing SharedLinkSettings

python - 小部件在弹出窗口上没有响应

python - 如何在 PyQt/PySide 中将 QComboBox 设置为项目文本中的项目

python - 在 PyQt 中将 QstringList 转换为 Qstring

python - 在 App Engine 应用程序初始化时执行代码

python - 在python中使相对路径成为绝对路径

python - 从Python客户端访问后端API

python - 在 python 类名中使用重音是一种不好的做法吗?