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

如何实现QLineEdit在Normal与Password模式间切换?按钮失效求助

问题原因

你的代码中Row类不是Qt控件的子类,当你将rowLayout添加到主布局后,Row实例没有被任何对象持有引用,会被Python的垃圾回收机制销毁。这导致按钮点击时,对应的槽函数hiddenOrShow已经不存在,无法执行切换逻辑。

修复方案

将Row类改为继承QWidget,把布局设置到Row实例上,然后将Row实例作为控件添加到主布局,而非直接添加布局。这样Row实例会被主窗口持有引用,不会被回收。

修改后的完整代码:

from sys import exit
from sys import argv
from PyQt6.QtWidgets import QApplication, QHBoxLayout, QPushButton, QVBoxLayout, QLabel, QWidget, QLineEdit

class MainWindow(QWidget):
    def __init__(self, parent=None) -> None:
        super().__init__(parent)
        self.screenWidth = 1920
        self.screenHeight = 1080
        self.windowWidth = 1000
        self.windowHeight = 800
        self.setWindowTitle("test 19")
        self.setGeometry((self.screenWidth - self.windowWidth) // 2, (self.screenHeight - self.windowHeight) // 2, self.windowWidth, self.windowHeight)
        self.initUi()
    
    def initUi(self) -> None:
        mainLayout = QVBoxLayout()
        headLayout = QHBoxLayout()
        nameLabel = QLabel("Name")
        headLayout.addWidget(nameLabel)
        mainLayout.addLayout(headLayout)
        row1 = Row("google.com")
        mainLayout.addWidget(row1)
        row2 = Row("yahoo.com")
        mainLayout.addWidget(row2)
        for i in range(20):
            rowi = Row(f"{i}")
            mainLayout.addWidget(rowi)
        self.setLayout(mainLayout)

class Row(QWidget):
    def __init__(self, name) -> None:
        super().__init__()
        self.rowLayout = QHBoxLayout(self)
        self.nameLineEdit = QLineEdit(f"{name}")
        self.nameLineEdit.setDisabled(True)
        self.rowLayout.addWidget(self.nameLineEdit)
        self.hiddenOrShowButton = QPushButton("切换")
        self.hiddenOrShowButton.clicked.connect(self.hiddenOrShow)
        self.rowLayout.addWidget(self.hiddenOrShowButton)
    
    def hiddenOrShow(self) -> None:
        if self.nameLineEdit.echoMode() == QLineEdit.EchoMode.Password:
            self.nameLineEdit.setEchoMode(QLineEdit.EchoMode.Normal)
        else:
            self.nameLineEdit.setEchoMode(QLineEdit.EchoMode.Password)


if __name__ == "__main__":
    app = QApplication(argv)
    window = MainWindow()
    window.show()
    exit(app.exec())
关键修改点
  • Row类继承QWidget,使其成为Qt控件对象,能被父布局持有引用。
  • 在Row的构造函数中,将布局直接绑定到当前实例(QHBoxLayout(self)),无需单独返回布局的方法。
  • 主窗口中调用mainLayout.addWidget(row)添加Row实例,而非直接添加布局。
  • 给按钮添加文本“切换”,方便识别点击区域(原按钮为空,可能难以精准点击)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 13:01:10