使用 PyQt5 获取或将插入的值转换为 int 或 float 的问题

问题描述 投票:0回答:1

感谢您来到这里。

我正在尝试使用 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,我插入初始和最终频率的值、步数并选择参考电阻 see image然后按下按钮并执行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”。有没有办法可以直接引用该值并进行转换。

帮助这位博士生,非常感谢!

python user-interface sdk pyqt5
1个回答
0
投票

您的

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()
也会返回最后选定的项目。

© www.soinside.com 2019 - 2024. All rights reserved.