Kivy & pyvisa - 如何在 GPIB 连接后将 ObjectProperty 设置为 None?
Posted
技术标签:
【中文标题】Kivy & pyvisa - 如何在 GPIB 连接后将 ObjectProperty 设置为 None?【英文标题】:Kivy & pyvisa - How to make an ObjectProperty to None after a GPIB connection? 【发布时间】:2021-03-21 17:40:54 【问题描述】:我正面临 kivy 和 pyvisa 的真正阻塞问题,我真的不知道如何找到解决方案。
在下面的代码中,我有一个名为“device”的 ObjectProperty,它被初始化为 None。我想用它来启动 GPIB 连接。当这个关闭时,我想再次将设备属性设置为无。
下面的所有代码都是尝试找到解决此问题的简单示例,但实际上我在实际应用程序中遇到了这个问题。此应用程序的功能之一是在列表中选择要使用的设备,我无法提前知道哪个设备可用或不可用,或者即使属性“设备”将在 GPIB 中连接或在另一个协议中。这就是为什么将它重置为无对我来说很重要的原因。
代码如下:
main.py
from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.properties import ObjectProperty, BooleanProperty, StringProperty
from pyvisa import ResourceManager
class NoneScreen(Screen):
# Properties
address = StringProperty('GPIB0::10::INSTR')
isConnected = BooleanProperty(False)
device = ObjectProperty(None)
# Connect/Disconnect very basicaly to a GPIB device
def connect(self):
if not self.isConnected:
print('Connect to', self.address)
rm = ResourceManager()
self.device = rm.open_resource(self.address)
self.isConnected = True
else:
print('Disconnect from', self.address)
self.device.close()
self.isConnected = False
# Test the state of the connection
def testCon(self):
try:
self.device.query('*IDN?')
except:
print('You are not connected')
else:
print('You are connected :)')
# Try something to make device properties None again
def noneFct(self):
self.device = None
# App
class MainApp(App):
def build(self):
ns = NoneScreen()
return ns
if __name__ == '__main__':
MainApp().run()
Main.kv
<NoneScreen>:
BoxLayout:
orientation: 'vertical'
Button:
text: 'Print'
on_release: print('self.device =', root.device)
Button:
text: 'Connect'
on_release: root.connect()
Button:
text: 'Test Connexion'
on_release: root.testCon()
Button:
text: 'Become None'
on_release: root.noneFct()
所以,这是我的问题:当我从 GPIB 连接和断开设备时,一切正常,但是当我尝试使“设备”在断开连接后返回 None 时,我遇到了这个错误:
self.device = None
Connect to GPIB0::10::INSTR
You are connected :)
self.device = GPIBInstrument at GPIB0::10::INSTR
Disconnect from GPIB0::10::INSTR
self.device = GPIBInstrument at GPIB0::10::INSTR
You are not connected
[INFO ] [Base ] Leaving application in progress...
Traceback (most recent call last):
File "C:\Users\Frederic\Desktop\debug\main.py", line 51, in <module>
MainApp().run()
File "C:\Users\Frederic\AppData\Local\Programs\Python\Python37\lib\site-packages\kivy\app.py", line 855, in run
runTouchApp()
File "C:\Users\Frederic\AppData\Local\Programs\Python\Python37\lib\site-packages\kivy\base.py", line 504, in runTouchApp
EventLoop.window.mainloop()
File "C:\Users\Frederic\AppData\Local\Programs\Python\Python37\lib\site-packages\kivy\core\window\window_sdl2.py", line 747, in mainloop
self._mainloop()
File "C:\Users\Frederic\AppData\Local\Programs\Python\Python37\lib\site-packages\kivy\core\window\window_sdl2.py", line 479, in _mainloop
EventLoop.idle()
File "C:\Users\Frederic\AppData\Local\Programs\Python\Python37\lib\site-packages\kivy\base.py", line 342, in idle
self.dispatch_input()
File "C:\Users\Frederic\AppData\Local\Programs\Python\Python37\lib\site-packages\kivy\base.py", line 327, in dispatch_input
post_dispatch_input(*pop(0))
File "C:\Users\Frederic\AppData\Local\Programs\Python\Python37\lib\site-packages\kivy\base.py", line 293, in post_dispatch_input
wid.dispatch('on_touch_up', me)
File "kivy\_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
File "C:\Users\Frederic\AppData\Local\Programs\Python\Python37\lib\site-packages\kivy\uix\behaviors\button.py", line 179, in on_touch_up
self.dispatch('on_release')
File "kivy\_event.pyx", line 703, in kivy._event.EventDispatcher.dispatch
File "kivy\_event.pyx", line 1214, in kivy._event.EventObservers.dispatch
File "kivy\_event.pyx", line 1098, in kivy._event.EventObservers._dispatch
File "C:\Users\Frederic\AppData\Local\Programs\Python\Python37\lib\site-packages\kivy\lang\builder.py", line 64, in custom_callback
exec(__kvlang__.co_value, idmap)
File "C:\Users\Frederic\Desktop\debug\main.kv", line 20, in <module>
on_release: root.noneFct()
File "C:\Users\Frederic\Desktop\debug\main.py", line 38, in noneFct
self.device = None
File "kivy\properties.pyx", line 497, in kivy.properties.Property.__set__
File "kivy\properties.pyx", line 541, in kivy.properties.Property.set
File "kivy\properties.pyx", line 532, in kivy.properties.Property.set
File "kivy\properties.pyx", line 1001, in kivy.properties.ObjectProperty.check
File "kivy\properties.pyx", line 570, in kivy.properties.Property.check
ValueError: None is not allowed for NoneScreen.device
所以,这就是为什么它对我来说很奇怪:如果我尝试做同样的事情,而不使用 kivy,在 python 命令行中,它可以工作!
>>> import pyvisa
>>> rm = pyvisa.ResourceManager()
>>> device = None
>>> print(device)
None
>>> device = rm.open_resource('GPIB0::10::INSTR')
>>> print(device)
GPIBInstrument at GPIB0::10::INSTR
>>> device.query('*IDN?')
'Agilent Technologies,33250A,0,2.01-1.01-1.00-03-2\n'
>>> device.close()
>>> print(device)
GPIBInstrument at GPIB0::10::INSTR
>>> device = None
>>> print(device)
None
所以,我真的不明白为什么它不起作用...... 有没有人知道如何解决这个问题?
注意:这是我在这里的第一篇文章,所以我希望所有内容都得到清楚的解释并且我没有犯错^^如果是这样,请告诉我!
【问题讨论】:
【参考方案1】:https://kivy.org/doc/stable/api-kivy.properties.html#kivy.properties.Property
None 是一种特殊情况:您可以将 Property 的默认值设置为 None,但以后不能将 None 设置为属性。如果你真的想这样做,你必须用 allownone=True 声明属性:
class MyObject(Widget):
hello = ObjectProperty(None, allownone=True)
# then later
a = MyObject()
a.hello = 'bleh' # working
a.hello = None # working too, because allownone is True.
改变
device = ObjectProperty(None)
到
device = ObjectProperty(None, allownone=True)
【讨论】:
哦,谢谢你成功了!显然,我在阅读文档时错过了这一点......你拯救了我的一天! 感谢您的反馈。很高兴你让它工作:)以上是关于Kivy & pyvisa - 如何在 GPIB 连接后将 ObjectProperty 设置为 None?的主要内容,如果未能解决你的问题,请参考以下文章
PyVISA - 无法让 GPIB 仪器以编程方式进入远程模式