感谢您来到这里。
我正在尝试使用 Python 开发 GUI,以便运行 Digilent 的 Analog Discovery 2 的阻抗分析器。到目前为止,我找到了适用于分析仪多种设置的 Waveforms ADK,并决定使用 PyQT5 作为接口工具,因为 TKinter 带来了一些令人头疼的问题。代码如下。
import PyQt5.QtWidgets as qtw
import PyQt5.QtGui as qtg
from ctypes import *
from dwfconstants1 import *
import math
import time
import sys
import numpy
import matplotlib.pyplot as plt
if sys.platform.startswith("win"):
dwf = cdll.LoadLibrary("dwf.dll")
elif sys.platform.startswith("darwin"):
dwf = cdll.LoadLibrary("/Library/Frameworks/dwf.framework/dwf")
else:
dwf = cdll.LoadLibrary("libdwf.so")
class MainWindow(qtw.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Impedance with AD2")
self.setLayout(qtw.QVBoxLayout())
my_label = qtw.QLabel("Insert values required to run impedance")
my_label.setFont(qtg.QFont('Helvetica',24))
self.layout().addWidget(my_label)
#Entry
start = qtw.QLineEdit()
start.setObjectName("start_frequency")
start.setText("Insert initial frequency in Hz")
self.layout().addWidget(start)
stop = qtw.QLineEdit()
stop.setObjectName("stop_frequency")
stop.setText("Insert final frequency in Hz")
self.layout().addWidget(stop)
steps = qtw.QLineEdit()
steps.setObjectName("stop_frequency")
steps.setText("Insert number of steps")
self.layout().addWidget(steps)
reference_resistor = qtw.QComboBox(self, editable = True, insertPolicy = qtw.QComboBox.InsertAtTop)
reference_resistor.addItem("1K", 1000)
reference_resistor.addItem("100", 100)
reference_resistor.addItem("10",10)
self.layout().addWidget(reference_resistor)
my_button = qtw.QPushButton("Launch measurement!", clicked = lambda: press_it())
self.layout().addWidget(my_button)
mytext = qtw.QTextEdit(self, acceptRichText = False, lineWrapMode =qtw.QTextEdit.FixedColumnWidth,
readOnly = False, placeholderText = "Hello World!")
version = create_string_buffer(16)
dwf.FDwfGetVersion(version)
hdwf = c_int()
szerr = create_string_buffer(512)
#print("Opening first device")
dwf.FDwfDeviceOpen(c_int(-1), byref(hdwf))
mytext.setText(f'DWF Version: "+str(version.value). "Opening first device"')
if hdwf.value == hdwfNone.value:
dwf.FDwfGetLastErrorMsg(szerr)
mytext.setText(f'DWF Version: +str(szerr.value). Failed to open device')
print(str(szerr.value))
print("failed to open device")
quit()
dwf.FDwfDeviceAutoConfigureSet(hdwf, c_int(3))
sts = c_byte()
self.show()
def press_it():
my_label.setText(f'Reference resistor is {reference_resistor.currentData()}')
#start.setText("")
mytext.setPlainText("Intended values of running AD2")
dwf.FDwfAnalogImpedanceReset(hdwf)
dwf.FDwfAnalogImpedanceModeSet(hdwf, c_int(8)) # 0 = W1-C1-DUT-C2-R-GND, 1 = W1-C1-R-C2-DUT-GND, 8 = AD IA adapter
dwf.FDwfAnalogImpedanceReferenceSet(hdwf, c_double(reference_resistor)) # reference resistor value in Ohms
dwf.FDwfAnalogImpedanceFrequencySet(hdwf, c_double(start.text)) # frequency in Hertz
dwf.FDwfAnalogImpedanceAmplitudeSet(hdwf, c_double(0.09)) # 1V amplitude = 2V peak2peak signal
dwf.FDwfAnalogImpedanceConfigure(hdwf, c_int(1)) # start
time.sleep(2)
rgHz = [0.0]*steps_
rgRs = [0.0]*steps_
rgXs = [0.0]*steps_
for i in range(steps):
hz = stop_ * pow(10.0, 1.0*(1.0*i/(steps-1)-1)*math.log10(stop_/start_)) # exponential frequency steps
print("Step: "+str(i)+" "+str(hz)+"Hz")
rgHz[i] = hz
dwf.FDwfAnalogImpedanceFrequencySet(hdwf, c_double(hz)) # frequency in Hertz
time.sleep(0.01)
dwf.FDwfAnalogImpedanceStatus(hdwf, None) # ignore last capture since we changed the frequency
while True:
if dwf.FDwfAnalogImpedanceStatus(hdwf, byref(sts)) == 0:
dwf.FDwfGetLastErrorMsg(szerr)
print(str(szerr.value))
quit()
if sts.value == 2:
break
resistance = c_double()
reactance = c_double()
dwf.FDwfAnalogImpedanceStatusMeasure(hdwf, DwfAnalogImpedanceResistance, byref(resistance))
dwf.FDwfAnalogImpedanceStatusMeasure(hdwf, DwfAnalogImpedanceReactance, byref(reactance))
rgRs[i] = abs(resistance.value) # absolute value for logarithmic plot
rgXs[i] = abs(reactance.value)
for iCh in range(2):
warn = c_int()
dwf.FDwfAnalogImpedanceStatusWarning(hdwf, c_int(iCh), byref(warn))
if warn.value:
dOff = c_double()
dRng = c_double()
dwf.FDwfAnalogInChannelOffsetGet(hdwf, c_int(iCh), byref(dOff))
dwf.FDwfAnalogInChannelRangeGet(hdwf, c_int(iCh), byref(dRng))
if warn.value & 1:
print("Out of range on Channel "+str(iCh+1)+" <= "+str(dOff.value - dRng.value/2)+"V")
if warn.value & 2:
print("Out of range on Channel "+str(iCh+1)+" >= "+str(dOff.value + dRng.value/2)+"V")
dwf.FDwfAnalogImpedanceConfigure(hdwf, c_int(0)) # stop
dwf.FDwfDeviceClose(hdwf)
plt.plot(rgHz, rgRs, rgHz, rgXs)
ax = plt.gca()
ax.set_xscale('log')
ax.set_yscale('log')
plt.show()
app = qtw.QApplication([])
mw = MainWindow()
app.exec_()
# create the instance of our Window
# start the app
sys.exit(app.exec())
这个想法是显示一个 GUI,我插入初始和最终频率的值、步数并选择参考电阻 然后按下按钮并执行Waveforms SDK运行阻抗扫描的部分,但出现此错误:
File c:\users\bforcure\documents\trials with pyqt5.py:91 in press_it
dwf.FDwfAnalogImpedanceReferenceSet(hdwf, c_double(reference_resistor.text)) # reference resistor value in Ohms
AttributeError: 'QComboBox' object has no attribute 'text'
如何将reference_resistor的值转换为整数?我尝试使用 int() ,它说只接受字符串或浮点数,而不接受“QComboBox”。有没有办法可以直接引用该值并进行转换。
帮助这位博士生,非常感谢!
您的
reference_resistor
是 QComboBox
。
就像错误消息告诉您的那样,
QComboBox
没有text
属性,
所以你的c_double(reference_resistor.text)
一定会失败。
QComboBox
的文档,
你会发现它有一个 currentText()
方法。
您可以使用它从组合框中获取当前值:
text = reference_resistor.currentText()
# you may want to add some error handling here, as your combobox is editable
resistor_value = int(text)
此外,您当前通过以下方式添加了一个电阻器:
reference_resistor.addItem("1K", 1000)
由于文本
"1K"
不是有效的整数,因此上面的代码片段不适用于这种情况,除非将其更改为“1000”。您似乎打算使用 userData
字段将该值从字段中获取。这可以使用 currentData()
方法而不是 currentText()
来完成,所以:
resistor_value = reference_resistor.currentData() #already an integer
在这种情况下,我建议使组合框不可编辑,因为即使在编辑文本后,
currentData()
也会返回最后选定的项目。