You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt6 QVariantAnimation经Cython编译后valueChanged信号无法触发问题

QVariantAnimation valueChanged Signal Not Triggering Slot After Cython Compilation to .pyd

I’ve run into this exact kind of PyQt/Cython signal-slot quirk before, so let’s break down what’s going on and how to fix it.

Problem Recap

When running your pure Python script, QVariantAnimation.valueChanged correctly fires and triggers your slot. But after compiling to a .pyd extension with Cython, only the finished signal works—valueChanged never calls your handler. Your environment details:

  • Python 3.11
  • PyQt6 6.4.0
  • Cython 3.0.0a11 (pre-release version)
  • Windows 11

Root Cause

The issue almost certainly comes down to how Cython handles the QVariant parameter in your @pyqtSlot(QVariant) decorator. Cython’s alpha/pre-release versions (like 3.0.0a11) often have incomplete support for PyQt’s type conversion between QVariant and native Python types. Since the finished signal has no parameters, it avoids this conversion bug—only valueChanged (which passes a QVariant) gets stuck.

Fixes to Try

1. Replace QVariant with a Native Python Type in the Slot Decorator

PyQt6 automatically converts QVariant values to native Python types (like float in your animation) when passing them to slots. Instead of declaring the slot with QVariant, use the actual Python type you expect:

# Replace @pyqtSlot(QVariant) with this:
@pyqtSlot(float)
def _on_animation_value_changed(self, value: float) -> None:
    print("Animation value changed to", value)

This bypasses Cython’s shaky QVariant handling by using a type it understands natively.

2. Remove the pyqtSlot Decorator Entirely

If the first fix doesn’t work, try dropping the @pyqtSlot decorator for the valueChanged handler. PyQt can dynamically infer slot signatures without explicit decorators, which might avoid Cython’s decorator-processing bugs:

# No @pyqtSlot decorator needed here
def _on_animation_value_changed(self, value: float) -> None:
    print("Animation value changed to", value)

Note: This has minor performance tradeoffs compared to explicit slots, but for animation handlers like this, it’s negligible.

3. Upgrade to a Stable Cython Version

Cython 3.0.0a11 is an alpha pre-release, meaning it’s still full of unpolished edges. Upgrading to the latest stable Cython 3.0.x release might resolve the QVariant handling bug outright—adjust your setup.py or requirements to use a stable build.

Modified Code Example

Here’s your widget with the first fix applied:

from PyQt6.QtCore import QAbstractAnimation, QVariantAnimation, pyqtSlot
from PyQt6.QtWidgets import QHBoxLayout, QPushButton, QWidget

class SampleWidget(QWidget):
    def __init__(self, parent: QWidget | None = None) -> None:
        super().__init__(parent)
        horizontal_layout = QHBoxLayout()
        horizontal_layout.setContentsMargins(0, 0, 0, 0)
        horizontal_layout.setSpacing(0)
        self.button = QPushButton(self)
        self.button.setText("Start animation")
        self.button.clicked.connect(lambda: self.start_animation(180))
        horizontal_layout.addWidget(self.button)
        self.setLayout(horizontal_layout)

    def start_animation(self, value: float) -> None:
        self._animation = QVariantAnimation(self)
        self._animation.setStartValue(0)
        self._animation.setEndValue(value)
        self._animation.setDuration(400)
        self._animation.valueChanged.connect(self._on_animation_value_changed)
        self._animation.finished.connect(self._on_animation_finished)
        self._animation.start(QAbstractAnimation.DeletionPolicy.DeleteWhenStopped)

    @pyqtSlot()
    def _on_animation_finished(self) -> None:
        print("Animation finished")

    @pyqtSlot(float)  # Updated from QVariant to float
    def _on_animation_value_changed(self, value: float) -> None:
        print("Animation value changed to", value)

Testing the Fix

After making these changes, recompile your extension with your existing Cython configuration and test again. The valueChanged signal should now trigger your slot correctly.

内容的提问来源于stack exchange,提问作者monotype

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 13:02:27