2013-09-23 3 views
0

У меня есть небольшой графический интерфейс с двумя простыми кнопками для доступа к модулю ввода-вывода LabJAck. Этот модуль используется для включения или выключения внешнего устройства, подключенного к нему. Я написал класс, который содержит устройство и несколько методов, чтобы сделать что-то с устройством, два из которых, включите и выключите. Причина, по которой я собираюсь получить доступ к LAbJack таким образом, заключается в том, что я хотел бы, чтобы код был красивым и аккуратным, и у меня будет несколько устройств, подключенных к моей машине, с каждым устройством, имеющим определенные команды ввода-вывода.Доступ к методам из классов в pyQT

Вот мой код Labjack:

import u3 

class LabJack: 
    def __init__(self): 

     try: 
      self.Switch = u3.U3() 
     except: 
      print "Labjack Error" 

     #Define State Registers for RB12 Relay Card 

     self.Chan0 = 6008 
     Chan1 = 6009 
     Chan2 = 6010 
     Chan3 = 6011 
     Chan4 = 6012 
     Chan5 = 6013 

    #Turn the channel on 
    def IO_On(self,Channel): 
     self.Switch.writeRegister(Channel,0) 


    #Turn the channel off 
    def IO_Off(self,Channel): 
     self.Switch.writeRegister(Channel,1) 

    #The State of the Channel 
    def StateSetting(self,Channel): 
     self.Switch.readRegister(Channel) 
     if Switch.readRegister(Channel) == 0: 
      print ('Channel is On') 
     else: 
      print('Channel is Off') 

    #Direction of Current Flow 
    def CurrentDirection(self,Channel): 
     self.Switch.readRegister(6108) 
     print self.Switch.readRegister(6108) 

Вот мой GUI код:

import re 
from PyQt4.QtCore import * 
from PyQt4.QtGui import * 
import sys 
from LabJackIO import * 
from Piezo902 import * 

import ui_aldmainwindow 

class ALDMainWindow(QMainWindow,ui_aldmainwindow.Ui_ALDMainWindow): 

    def __init__(self, parent=None): 
     super(ALDMainWindow,self).__init__(parent) 
     self.setupUi(self) 

     self.ValveControl = LabJack() 

     self.Valve_ON.clicked.connect(self.ValveControl.IO_On(6008)) 
     self.Valve_OFF.clicked.connect(self.ValveControl.IO_Off(self.ValveControl.Chan0)) 
     self.statusBar().showMessage('Valve Off') 

app = QApplication(sys.argv) 
app.setStyle('motif') 
form = ALDMainWindow() 
form.show() 
app.exec_() 

При выполнении кода я получаю следующее сообщение об ошибке:

Traceback (most recent call last): 
    File "ALDSoftwareMainWindow.py", line 26, in <module> 
    form = ALDMainWindow() 
    File "ALDSoftwareMainWindow.py", line 20, in __init__ 
    self.Valve_ON.clicked.connect(self.ValveControl.IO_On(6008)) 
TypeError: connect() slot argument should be a callable or a signal, not 'int' 

я не могу понять, что я делаю неправильно. Любая помощь будет принята с благодарностью.

Спасибо.

+0

также см. Http://stackoverflow.com/questions/18925241/send-additional-variable-during-pyqt-pushbutton-click – tacaswell

ответ

1

1 Использование partial возможно лучший способ.

self.Valve_ON.clicked.connect(functools.partial(self.ValveControl.IO_on,6008)) 

2 Использование QSignalMapper.

+0

Спасибо, отлично работал !!!! –

+0

Как добавить self.statusBar(). ShowMessage(), который будет запущен после Valve_On/Off.clicked.connect? –

1

Вы вызываете метод, который вы подключаетесь кнопкой:

self.Valve_ON.clicked.connect(self.ValveControl.IO_On(6008)) 

Вероятно, это будет исправить вашу проблему:

self.Valve_ON.clicked.connect(lambda: self.ValveControl.IO_On(6008)) 

lambda является анонимной функцией, которая будет отложить созыв вашего метода IO_ON(6008), пока кнопка не будет нажата.

+0

Это будет работать в этом случае, но будьте осторожны с хитросплетенными ловушками закрытия. – tacaswell

+0

Нравится что ?. Мне нравятся хитроумные ловушки закрытия, в то время как я делаю серьезные вещи, я не знаю о вас (проклятье минимальное требование длины сообщения). – MadeOfAir

+0

См. Вопрос, связанный в моем ответе.Я делал что-то вроде этого, но я генерировал 'лямбда' из значений в списке и в итоге привязывал значение _last_ к списку. – tacaswell

1

У вас есть неправильное понимание того, как работают слоты/сигналы. Аргумент connect должен быть функцией, которая принимает в качестве аргумента, какой сигнал вы подключаете к испусканию. В этом случае, похоже, вы подключаетесь к сигналу clicked с помощью кнопки (которая не содержит значений). Поэтому вам нужно обернуть функцию, которую вы хотите вызвать, в функции, которая не принимает аргументов. Самый простой способ сделать это, чтобы обернуть функции в lambda функции:

self.Valve_ON.clicked.connect(lmabda x=6008: self.ValveControl.IO_On(x)) 
self.Valve_OFF.clicked.connect(lambda x=self.ValveControl.Chan0: self.ValveControl.IO_Off(x)) 

, который создает функцию с одним дополнительным аргументом (который по умолчанию значения, которые вы хотите), поэтому он будет работать как слот без аргументов.

Это может показаться странным использовать аргумент по умолчанию, чтобы связать значение, но она предотвращает некоторые странные кажущиеся проблемы с закрытием (см Python lambda closure scoping)

Другой способ заключается в использовании functools.partial, чтобы обернуть ваши функции.

Смежные вопросы