在 PyQt5 中使用全局信号

本文介绍了如何在PyQt5中创建和使用全局信号,包括定义继承自QObject的类、信号成员、全局变量以及在不同类间发送和接收信号的过程。
摘要由CSDN通过智能技术生成

在 PyQt5 中使用全局信号

  Qt 的信号和槽机制在不同界面间交换控制和消息,是一个很有用的机制。有时为了在不同界面对象甚至不同线程间使用这一机制,需要建立全局的信号变量。
  需要注意的是:不能简单地用 signal_inst = pyqtSignal() 建立信号实例。信号实例必须是一个继承自 QObject 类的类成员,否则运行 connect 时会报错,无法正常工作。因此,建立和使用信号实例须经历以下步骤:
  1. 定义一个继承自 PyQt5.QtCore.QObject 的类;
  2. 在类中定义一个或多个 pyqtSignal 类成员;
  3. 用定义的类生成一个全局变量;
  4. 在发送信号(emit)和接收信号(connect)的模块中,引入该全局变量;
  5. 按照正常的方式使用信号和槽。

  下面是全局变量定义文件,文件名为global_var.py,实现上述的 1、2、3 三个步骤:

from PyQt5.QtCore import pyqtSignal, QObject


# 定义派生自 QObject 的类
class SignalGroup(QObject):
	# 在类中定义信号
    repaint_signal = pyqtSignal(str)


# 定义全局变量,供发送和接收程序调用
signal_object = SignalGroup()

  下面是发送和接收信号的测试程序文件,文件名为 any_test.py:

# 引入全局变量 signal_object
from global_vars import signal_object


# 这是发送信号的类
class A:
    def __init__(self, s=''):
        super().__init__()
        # self.sig_string 是用于发送的参数
        self.sig_string = s

    # 发送方法
    def send_sig(self):
    	# 发送信号
        signal_object.repaint_signal.emit(self.sig_string)


# 这是接收信号的类
class B:
    def __init__(self, inst_name=""):
        super().__init__()
        self.test_string = inst_name + " get signal: "
        # 定义槽
        signal_object.repaint_signal.connect(self.test_sig)

    # 接收方法,s 是接收到的参数
    def test_sig(self, s):
        print(self.test_string + s)


if __name__ == "__main__":
    # 发送对象实例
    a = A('signal from a')
    # 两个接收对象实例
    b = B("inst b")
    b1 = B("inst b1")

    a.send_sig()

  在主程序中,我们生成了一个发送类(A)的实例(a),两个接收类(B)的实例(b,b1),运行any_test.py,得到如下输出:

inst b get signal: signal from a
inst b1 get signal: signal from a

Process finished with exit code 0

  从输出可以看出,两个接收实例都收到了发送实例发出的信号。

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
A: 首先,你需要将 PyQT 类导入到 C++ 代码。 在 C++ ,你需要使用 Python/C API 来调用 Python 代码。以下代码展示了如何使用 Python/C API 的 PyRun_SimpleString() 函数来执行 Python 代码: ```cpp #include <Python.h> int main(int argc, char *argv[]) { Py_Initialize(); // 初始化 Python 环境 // 执行 Python 代码 PyRun_SimpleString("import sys\n" "print(sys.version)\n"); Py_Finalize(); // 释放 Python 环境 return 0; } ``` 接下来,我们需要使用之前生成的 PyQT 类来更新标签的文本。 在 PyQt,你需要添加一个新的槽函数并将其连接到适当的信号。在 C++ 代码,你可以使用 PyObject_CallObject() 函数来调用 Python 槽函数。以下是一个示例代码: ```cpp #include <Python.h> #include "pyqt_wrapper.h" // 包含 PyQT 类的头文件 PyObject *pModule = NULL; // 保存 Python 模块的全局变量 PyObject *pInstance = NULL; // 保存 Python 类的实例的全局变量 int main(int argc, char *argv[]) { Py_Initialize(); PyEval_InitThreads(); PyThreadState *pThread = PyEval_SaveThread(); // 保存当前线程状态 PyRun_SimpleString("import sys\n" "sys.path.append('./')\n" "import pyqt_wrapper\n" "app = pyqt_wrapper.PyQtApp()\n" "label = app.add_label('Hello, C++!')\n" "label.clicked.connect(app.label_clicked)\n"); // 加载 Python 模块并创建标签 PyEval_RestoreThread(pThread); // 恢复之前保存的线程状态 PyGILState_STATE gstate = PyGILState_Ensure(); // 获取 GIL pModule = PyImport_ImportModule("pyqt_wrapper"); if (pModule == NULL) { Py_DECREF(pModule); PyErr_Print(); return 1; } PyObject *pApp = PyObject_GetAttrString(pModule, "app"); // 获取 PyQT 应用程序的实例 if (pApp == NULL) { Py_DECREF(pModule); Py_DECREF(pApp); PyErr_Print(); return 1; } pInstance = PyObject_CallMethod(pApp, "get_label", "s", "Hello, C++!"); if (pInstance == NULL) { Py_DECREF(pModule); Py_DECREF(pApp); Py_DECREF(pInstance); PyErr_Print(); return 1; } PyObject_CallMethod(pInstance, "set_text", "s", "Updated text!"); // 调用 Python 方法更新标签文本 PyObject *pLabelClickedSlot = PyObject_GetAttrString(pModule, "label_clicked"); if (pLabelClickedSlot == NULL) { Py_DECREF(pModule); Py_DECREF(pApp); Py_DECREF(pInstance); Py_DECREF(pLabelClickedSlot); PyErr_Print(); return 1; } PyObject_CallObject(pInstance, pLabelClickedSlot); // 调用槽函数 Py_DECREF(pModule); Py_DECREF(pApp); Py_DECREF(pInstance); Py_DECREF(pLabelClickedSlot); PyGILState_Release(gstate); // 释放 GIL Py_Finalize(); return 0; } ``` 在 C++ 代码,我们首先创建了一个 PyQT 应用程序对象和一个标签,并将标签的 clicked 信号连接到一个 Python 槽函数。然后,我们创建了一个新的 Python 对象实例,并更新了标签的文本。最后,我们还演示了如何调用 Python 槽函数。 请注意,由于我们在 C++ 代码调用 Python 代码,所以我们需要在 C++ 代码管理 Python 对象的生命周期。我们使用 Py_DECREF() 函数来释放在 C++ 代码创建的 Python 对象。 你需要将以下 C++ 代码保存为一个名为 "main.cpp" 的文件,并将 "pyqt_wrapper.h" 头文件和 "pyqt_wrapper.so" 动态库文件复制到同一个目录,然后使用以下命令从命令行编译并运行代码: ```bash g++ main.cpp -I/usr/include/python3.6 -lpython3.6 -o main && ./main ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值