点击连接信号不会执行回调

时间:2016-10-25 15:12:21

标签: python-2.7 pyqt pyqt4 signals-slots qt-designer

我试图用QtDesigner和PyQT 4.11在python 2.7中创建一个应用程序。

在应用程序中,我希望有两个QPushButtons在单击时更改QSpinBox的值。我已经阅读了有关Signal Slot机制问题的几页StackOverflow答案,但无法找到问题的答案。

我使用pyuic4生成Ui_W_Setup.py,这里是相关部分:

class Ui_W_Setup(object):
  def setupUi(self, W_Setup):
    W_Setup.setObjectName(_fromUtf8("W_Setup"))
    self.Motorsteuerung = QtGui.QDockWidget(W_Setup)
    self.Motorsteuerung.setEnabled(True)
    self.Motorsteuerung.setMinimumSize(QtCore.QSize(140, 365))
    self.Motorsteuerung.setFeatures(QtGui.QDockWidget.DockWidgetFloatable|QtGui.QDockWidget.DockWidgetMovable)
    self.Motorsteuerung.setAllowedAreas(QtCore.Qt.LeftDockWidgetArea)
    self.Motorsteuerung.setObjectName(_fromUtf8("Motorsteuerung"))
    self.dockWidgetContents = QtGui.QWidget()
    self.dockWidgetContents.setObjectName(_fromUtf8("dockWidgetContents"))
    self.B_ZuNehm = QtGui.QPushButton(self.dockWidgetContents)
    self.B_ZuNehm.setGeometry(QtCore.QRect(40, 250, 81, 71))
    self.B_ZuNehm.setObjectName(_fromUtf8("B_ZuNehm"))

    self.B_ZuTast = QtGui.QPushButton(self.dockWidgetContents)
    self.B_ZuTast.setGeometry(QtCore.QRect(40, 180, 81, 71))
    self.B_ZuTast.setObjectName(_fromUtf8("B_ZuTast"))

    self.SB_Position = QtGui.QDoubleSpinBox(self.dockWidgetContents)
    self.SB_Position.setGeometry(QtCore.QRect(40, 21, 81, 31))
    font = QtGui.QFont()
    font.setPointSize(10)
    self.SB_Position.setFont(font)
    self.SB_Position.setFrame(True)
    self.SB_Position.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
    self.SB_Position.setButtonSymbols(QtGui.QAbstractSpinBox.NoButtons)
    self.SB_Position.setSpecialValueText(_fromUtf8(""))
    self.SB_Position.setCorrectionMode(QtGui.QAbstractSpinBox.CorrectToNearestValue)
    self.SB_Position.setDecimals(1)
    self.SB_Position.setMaximum(50.0)
    self.SB_Position.setSingleStep(0.2)
    self.SB_Position.setProperty("value", 0.0)
    self.SB_Position.setObjectName(_fromUtf8("SB_Position"))

然后我有一个主python文件来加载ui.py并执行应用程序:

import sys
from PyQt4 import QtGui,QtCore
from Setup import Ui_W_Setup

app = QtGui.QApplication(sys.argv)

class MainWindow(QtGui.QMainWindow, Ui_W_Setup):
  def __init__(self):
    QtGui.QMainWindow.__init__(self)
    self.setupUi(self)

    motor = MotorClass()

    self.B_ZuNehm.clicked.connect(motor.zuNehm)
    self.B_ZuTast.clicked.connect(motor.zuTast)

class MotorClass(QtCore.QObject):
  def __init__(self):
    super(MotorClass, self).__init__()

  global window
  confirm = QtGui.QMessageBox()
  confirm.setText('Verfahrweg frei?')
  confirm.setStandardButtons(QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)
  confirm.setDefaultButton(QtGui.QMessageBox.Yes)

  @QtCore.pyqtSlot() #shouldnt be needed with my current knowledge
  def zuNehm(self):
    print("TestNehm")
    response = self.confirm.exec_()
    if response == 16384: #seems to be the return value for "Yes"
      window.SB_Position.setValue(float(1))

  @QtCore.pyqtSlot() #shouldnt be needed aswell with my current knowledge
  def zuTast(self):
    print("TestTast")
    response = self.confirm.exec_()
    if response == 16384:
      window.SB_Position.setValue(float(2))


def main():
  global window   #I dont like declaring it globally , is there a better way
  window = MainWindow()

  window.show()
  sys.exit(app.exec_())

if __name__ == '__main__':
  main()

没有抛出任何表现,打印机也不会出现在控制台中。

2 个答案:

答案 0 :(得分:0)

例如此行>>

self.B_FileOpen.clicked.connect(fileSelect)

进行此连接时,您的函数“fileSelect”仍然不存在。

在宣布所有声明后尝试进行“连接”。

如果不是“fileSelect”特别是其他一些。但是,当您尝试连接尚未声明的内容时,通常会出现此行为。

答案 1 :(得分:0)

信号连接不起作用,因为您没有保留对您创建的MotorClass实例的引用。当它被垃圾收集时,信号连接会自动删除。

下面的代码修复了此问题,以及MotorClass的其他一些问题(例如对window变量的全局引用)。

class MainWindow(QtGui.QMainWindow, Ui_W_Setup):
  def __init__(self):
    QtGui.QMainWindow.__init__(self)
    self.setupUi(self)
    self.motor = MotorClass(self)
    self.B_ZuNehm.clicked.connect(self.motor.zuNehm)
    self.B_ZuTast.clicked.connect(self.motor.zuTast)

class MotorClass(QtCore.QObject):
  def __init__(self, parent):
    super(MotorClass, self).__init__(parent)
    self.confirm = QtGui.QMessageBox()
    self.confirm.setText('Verfahrweg frei?')
    self.confirm.setStandardButtons(QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)
    self.confirm.setDefaultButton(QtGui.QMessageBox.Yes)

  def zuNehm(self):
    print("TestNehm")
    response = self.confirm.exec_()
    if response == QtGui.QMessageBox.Yes:
      self.parent().SB_Position.setValue(float(1))

  def zuTast(self):
    print("TestTast")
    response = self.confirm.exec_()
    if response == QtGui.QMessageBox.Yes:
      self.parent().SB_Position.setValue(float(2))

def main():
  app = QtGui.QApplication(sys.argv)
  window = MainWindow()
  window.show()
  sys.exit(app.exec_())