"QPushButton"没有属性"clicked"根据mypy



当我使用--strict标志运行mymyy时,它会抱怨"QPushButton"没有属性"click"。Pycharm也抱怨这个问题。尽管如此,代码运行良好。例如:

import sys
from PySide6.QtWidgets import QApplication, QPushButton, QVBoxLayout, QWidget

class Window(QWidget):
def __init__(self) -> None:
super().__init__()
self.setWindowTitle("My App")
self.resize(500, 500)
layout = QVBoxLayout()
self.btn = QPushButton("Click Me")
self.btn.clicked.connect(self.btn_clicked)
layout.addWidget(self.btn)
self.setLayout(layout)
self.show()
def btn_clicked(self) -> None:
print("Button clicked")

app = QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec())

运行mypy . --strict会引发以下错误:

example.py:13: error: "QPushButton" has no attribute "clicked"
Found 1 error in 1 file (checked 1 source file)

我做的是不好的练习吗?大多数在线文档,包括Qt的官方Python文档都说以这种方式将按钮连接到函数。

如果这不是不好的做法,是否有一种方法使Pycharm和mymy不抱怨这种连接按钮的方式?

正如@noEmbryo和@ekhumoro在评论中所写的那样:

我在做什么不好的做法?

你遵循了官方文档,你所做的是正确的。问题是在为PySide生成的类型中存在一个错误。PySide/Qt是用c++编写的,只有Python绑定为它生成。

Python的Typing支持是相当新的,仍在积极开发中。所以通常你会在使用它的时候遇到麻烦。这也意味着没有直接的方法将c++类型信息转换为Python类型信息。

是否有一种方法可以使Pycharm和mymy不抱怨这种连接按钮的方式?

是的。有三种可能:

  1. 等待直到PySide(即6.5.0版本,但如果你看相关问题,也有一些旧版本的后端)修复错误

  2. 忽略给定的错误(暂时在PySide上游不固定)

self.btn.clicked.connect(self.btn_clicked)  # type: ignore[attr-defined]
  1. 在按钮周围创建一个包装器,告诉类型检查器,被点击的属性实际上是存在的,并且是一个信号。
import sys
from PySide6.QtWidgets import QApplication, QPushButton, QVBoxLayout, QWidget
from PySide6.QtCore import Signal
class QPushButtonWithSignals(QPushButton):
"""Remove attributes below once Signal typing issues are fixed upstream"""
clicked: Signal
# Add other missing Signals here if used

class Window(QWidget):
def __init__(self) -> None:
super().__init__()
self.setWindowTitle("My App")
self.resize(500, 500)
layout = QVBoxLayout()
self.btn = QPushButtonWithSignals("Click Me")
self.btn.clicked.connect(self.btn_clicked)
…

相关内容

  • 没有找到相关文章

最新更新