如何使用 PyQt 信号发出 64 位无符号整数

How to emit a 64 bit unsigned integer with a PyQt signal

提问人:PiRK 提问时间:11/14/2023 更新时间:11/14/2023 访问量:49

问:

我过去使用时遇到了整数溢出问题,因为似乎 python int 在 C++ 调用中变成了 C int(32 位有符号整数)。这将信号可以发出的最大值限制为 2,147,483,647。PyQt5.QtCore.pyqtSignal(int)

我通过发射来解决这个问题,但我想这会增加信号的开销。PyQt5.QtCore.pyqtSignal(object)

有没有办法准确指定我希望信号在我的 python 代码中发出哪种整数类型?

python pyqt pyqt5 整数溢出

评论

1赞 ekhumoro 11/15/2023
使用不会带来任何显着的开销,因为PyQt将发送指针,而不是从Python类型转换为C++类型(如果接收器是Python插槽,则再次返回)。您是否绝对确定此 API 永远不会发送大小不受限制的整数?object
0赞 PiRK 11/17/2023
@ekhumoro 感谢您提供有关指针的有用信息。就我而言,我确信我的 int 将永远是 a(它是比特币交易中的聪数)。uint64
0赞 PiRK 11/17/2023
最大的问题是,如果PyQt足够聪明,可以对任意对象使用指针,那么为什么PyQt在我希望它传递python时选择传递一个?int32int
0赞 ekhumoro 11/17/2023
PyQt并不聪明。它对一些基本类型进行自动转换,但除此之外只是拒绝猜测。始终转换为 32 位值的原因在很大程度上是历史原因。早期版本的 PyQt 需要使用 C++ 和宏,因此设计决策部分受到易于移植和/或向后兼容性的影响。但更重要的是,这一切都发生在 PEP 237 之前,所以 Python 仍然会同时拥有两者。intSIGNALSLOTintlong
0赞 ekhumoro 11/17/2023
所以:在过去,你可以使用 ,但现在你必须使用(根据 PyQt 文档),或者可能(保证在所有平台上都是相同的大小)。longobject"quint64"

答:

1赞 PyariBilli 11/14/2023 #1

在使用 PyQt 并处理信号插槽机制时,尤其是对于大整数时,您遇到的问题确实是由于 Python 在使用 时被转换为 C++。由于 C++ 中的 32 位有符号整数限制,此转换限制了整数大小。intintpyqtSignal(int)

使用是一种解决方法,因为它允许 Python 对象(包括 Python 的无限大小 )通过信号传输。但是,正如您正确指出的那样,由于 Python 对象的动态特性,这可能会增加开销。pyqtSignal(object)int

要指定整数的确切类型,可以使用PyQt提供的特定C++整数类型。这些类型包括 、 和 32 位和 64 位整数,包括有符号和无符号。以下是使用它们的方法:QtCore.pyqtSignalquint32qint64quint64

  1. 对于 64 位有符号整数:用于创建可以处理 64 位有符号整数的信号。这会将限额增加到 ±9,223,372,036,854,775,807。QtCore.pyqtSignal('qint64')

    from PyQt5.QtCore import pyqtSignal, QObject
    
    class MyEmitter(QObject):
        mySignal = pyqtSignal('qint64')
    
        def emit_signal(self, value):
            self.mySignal.emit(value)
    
  2. 对于 64 位无符号整数:如果需要无符号 64 位整数,则使用该整数,该整数允许最大值为 18,446,744,073,709,551,615。QtCore.pyqtSignal('quint64')

    mySignal = pyqtSignal('quint64')
    

通过使用这些类型指定信号,可以避免使用开销,并且仍然具有比默认 32 位范围更大的整数值范围。在传递的数据类型方面,它也更加精确,这在 Python 和 Qt 开发中通常是很好的做法。object

请记住在连接到它们的插槽中适当地处理这些信号,确保插槽功能与信号的数据类型兼容。

评论

1赞 ekhumoro 11/15/2023
这个答案恰恰是倒退的。如果使用,则几乎没有开销,因为PyQt将简单地传递指针。这意味着发送的参数将与接收到的参数完全相同(即它将满足测试)。相比之下,使用 C++ 类型会带来更多的开销,因为每次触发信号时都必须将参数从 Python 类型转换为 C++ 类型(可能再次转换回来)。除非接收器实际上需要特定类型,否则这样做通常没有什么意义 - 对于大多数 Python 插槽来说,这种情况很少见。objectis
0赞 ekhumoro 11/15/2023
当然,在某些情况下,发送指针可能是不可取的 - 例如,在发出跨线程信号时可能存在线程安全考虑。但更一般地说,在这种情况下,从一些神话般的“最佳实践”的角度来思考是错误的。在编组 Python 和 C++ 之间的参数时,通常需要考虑更重要的实际问题。在没有任何实际理由的情况下强加类型限制通常是不合时宜的,甚至可能导致微妙的错误。