从PyQt的QPushButton获取文本

3 投票
2 回答
5444 浏览
提问于 2025-04-17 10:55

我正在尝试用一组QtGui.QPushButton对象来创建一个简单的键盘。

class XKeyboard(QtGui.QWidget):
  '''Special virtual keyboard for any language.'''
  def __init__(self, parent=None):
    QtGui.QWidget.__init__(self, parent)
    self.MainLayout = QtGui.QVBoxLayout()
    self.TextEntry = QtGui.QTextEdit()
    self.Keyboard = QtGui.QVBoxLayout()
    self.MainLayout.addWidget(self.TextEntry)
    self.MainLayout.addLayout(self.Keyboard)
    self.setLayout(self.MainLayout)

  def addRow(self, keys):
    layout = QtGui.QHBoxLayout()
    buttons = [QtGui.QPushButton(unicode(key)) for key in keys]
    for button in buttons:
      key = keys[buttons.index(button)]
      layout.addWidget(button)
      button.clicked.connect(
          lambda key: self.keyClick(key))
      self.keyClick(key)
    self.Keyboard.addLayout(layout)

  def keyClick(self, key):
    self.TextEntry.insertPlainText(key)

问题是,lambda函数返回的是False,而不是我想要的键。请问我哪里出错了?

2 个回答

3

正确的做法是使用一个叫做 QButtonGroup 的东西,它就是为这种情况设计的。

下面是一个改写你例子的方式,来使用这个东西:

class XKeyboard(QtGui.QWidget):
  '''Special virtual keyboard for any language.'''
  def __init__(self, parent=None):
    QtGui.QWidget.__init__(self, parent)
    self.MainLayout = QtGui.QVBoxLayout()
    self.TextEntry = QtGui.QTextEdit()
    self.Keyboard = QtGui.QVBoxLayout()
    self.MainLayout.addWidget(self.TextEntry)
    self.MainLayout.addLayout(self.Keyboard)
    self.setLayout(self.MainLayout)
    self.buttonGroup = QtGui.QButtonGroup(self)
    self.buttonGroup.buttonClicked[int].connect(self.keyClick)

  def addRow(self, keys):
    layout = QtGui.QHBoxLayout()
    for key in keys:
        key = unicode(key)
        button = QtGui.QPushButton(key)
        self.buttonGroup.addButton(button, ord(key))
        layout.addWidget(button)
    self.Keyboard.addLayout(layout)

  def keyClick(self, key):
    self.TextEntry.insertPlainText(unichr(key))
5

这个 lambda :

lambda key: self.keyClick(key)

其实和这个是一样的:

def dummy(key):
    self.keyClick(key)

简单来说,你是在接受一个来自 clicked 信号的参数,这个信号会返回按钮的 checked 状态。因为你没有可勾选的按钮,所以这个状态是 False,然后把这个状态传给 keyClick 方法。需要注意的是,keyClick 方法在循环中并没有接收到 key 参数。

一个可能的解决办法是写一个 lambda,让它接受两个参数,其中一个参数的默认值是你想要的值:

lambda checked, key=key: self.keyClick(key)

至于为什么要写 key=key,这是另一个话题。你可以参考 这个特定的回答(还有其他相关的回答)来了解更多信息。

撰写回答