基于PySide6/PyQt6的GPD系列直流电源驱动程序

目录

一、前期准备  

二、代码部分

1、串口设置

2、输出电流/电压的设置和读取

3、 定制功能——电流脉冲

4、实时输出数据图绘制

三、实际效果演示


一、前期准备  

        我们在官网可以找到GPD系列的数据手册,在数据手册能找到该系列电源的控制方式,我们的程序也就据此展开:

二、代码部分

1、串口设置

        根据数据手册说明,我们可完成对串口的基本设置

        

        该部分界面代码示例:

    def SerialSetting(self):
        self.GropuBox_SerialSetting=QGroupBox('串口设置')
        self.FormLayout_SerialSetting=QFormLayout()
        self.ComboBox_SerialPort=MyComboBox()
        self.ComboBox_SerialPort.clicked.connect(self.DetectSerialPort)
        self.FormLayout_SerialSetting.addRow('串口选择:',self.ComboBox_SerialPort)
        self.ComboBox_BaudRate=QComboBox()
        self.ComboBox_BaudRate.addItems(['9600','57600','115200'])
        self.FormLayout_SerialSetting.addRow('波特率:',self.ComboBox_BaudRate)
        self.PushButton_ToggleSerial=QPushButton('打开串口')
        self.PushButton_ToggleSerial.setCheckable(True)  # 设置按钮为切换按钮
        self.PushButton_ToggleSerial.clicked.connect(self.ToggleSerialPort)
        self.FormLayout_SerialSetting.addRow(self.PushButton_ToggleSerial)
        self.GropuBox_SerialSetting.setLayout(self.FormLayout_SerialSetting)
        return self.GropuBox_SerialSetting

       界面实际效果图:

        串口功能函数,主要用于获取可用串口以及按照配置打开串口。

    def DetectSerialPort(self):
        self.ComboBox_SerialPort.clear()
          #获取可用串口
        SerialPortList=[x.portName()+' '+x.description() for x in QSerialPortInfo.availablePorts()]
        for port in SerialPortList:
            self.ComboBox_SerialPort.addItem(port)

    def ToggleSerialPort(self):
        if self.PushButton_ToggleSerial.isChecked():
            try:
                # 打开串口
                port_name = self.ComboBox_SerialPort.currentText().split()[0]  # 获取选中的串口名称
                baud_rate = int(self.ComboBox_BaudRate.currentText())
              
                self.SerialPort.setPortName(port_name)
                self.SerialPort.setBaudRate(baud_rate)
                self.SerialPort.setDataBits(QSerialPort.Data8)
                self.SerialPort.setStopBits(QSerialPort.OneStop)
                self.SerialPort.setParity(QSerialPort.NoParity)
                self.SerialPort.setFlowControl(QSerialPort.NoFlowControl)

                if self.SerialPort.open(QSerialPort.ReadWrite):
                    print("串口打开成功")
                    self.ComboBox_SerialPort.setEnabled(False)
                    self.ComboBox_BaudRate.setEnabled(False)
                    self.PushButton_ToggleSerial.setText("关闭串口")
                    self.PushButton_ToggleSerial.setStyleSheet("background-color: red; color: black;")
                else:
                    print("无法打开串口")
                    QMessageBox.critical(self, "错误", "无法打开串口")
            except Exception as e:
                QMessageBox.critical(self, "错误", "请选择串口")
        else:
            # 关闭串口
            self.SerialPort.close()
            self.ComboBox_SerialPort.setEnabled(True)
            self.ComboBox_BaudRate.setEnabled(True)
            self.PushButton_ToggleSerial.setText("打开串口")
            self.PushButton_ToggleSerial.setStyleSheet("background-color: white; color: black;")

2、输出电流/电压的设置和读取

        在数据手册里,我们能找到控制用的指令,图中红框所圈出来就是接下来所需用到的指令。

        该部分界面代码示例:

   def CurrentControl(self):
        self.GropuBox_CurrentControl=QGroupBox('电流控制')
        self.FormLayout_CurrentControl=QFormLayout()

        self.ComboBox_CurrentChannel=QComboBox()
        self.ComboBox_CurrentChannel.addItems(['CH1','CH2'])
        self.FormLayout_CurrentControl.addRow('电流通道',self.ComboBox_CurrentChannel)

        self.LineEdit_CurrentSet=QLineEdit()
        self.LineEdit_CurrentSet.setAlignment(QtCore.Qt.AlignCenter)
        self.PushButton_CurrentSet=QPushButton('设置')
        self.PushButton_CurrentSet.clicked.connect(self.SetCurrent)
        self.hbox1 = QHBoxLayout()
        self.hbox1.addWidget(self.LineEdit_CurrentSet)
        self.hbox1.addWidget(QLabel('A'))
        self.hbox1.addWidget(self.PushButton_CurrentSet)

        self.FormLayout_CurrentControl.addRow('电流设置',self.hbox1)
        self.LineEdit_CurrentRead=QLineEdit()
        self.LineEdit_CurrentRead.setAlignment(QtCore.Qt.AlignCenter)
        self.PushButton_CurrentRead=QPushButton('读取')
        self.PushButton_CurrentRead.clicked.connect(self.ReadCurrent)
        self.hbox2 = QHBoxLayout()
        self.hbox2.addWidget(self.LineEdit_CurrentRead)
        self.hbox2.addWidget(QLabel('A'))
        self.hbox2.addWidget(self.PushButton_CurrentRead)
        self.FormLayout_CurrentControl.addRow('电流读取',self.hbox2)

        self.GropuBox_CurrentControl.setLayout(self.FormLayout_CurrentControl)
        return self.GropuBox_CurrentControl
    def VoltageControl(self):
        self.GropuBox_VoltageControl=QGroupBox('电压控制')
        self.FormLayout_VoltageControl=QFormLayout()
        self.ComboBox_VoltageChannel=QComboBox()

        self.ComboBox_VoltageChannel.addItems(['CH1','CH2'])
        self.FormLayout_VoltageControl.addRow('电压通道',self.ComboBox_VoltageChannel)

        self.LineEdit_VoltageSet=QLineEdit()
        self.LineEdit_VoltageSet.setAlignment(QtCore.Qt.AlignCenter)
        self.PushButton_VoltageSet=QPushButton('设置')
        self.PushButton_VoltageSet.clicked.connect(self.SetVoltage)

        self.hbox1 = QHBoxLayout()
        self.hbox1.addWidget(self.LineEdit_VoltageSet)
        self.hbox1.addWidget(QLabel('V'))
        self.hbox1.addWidget(self.PushButton_VoltageSet)
        self.FormLayout_VoltageControl.addRow('电压设置',self.hbox1)
        
        self.LineEdit_VoltageRead=QLineEdit()
        self.LineEdit_VoltageRead.setAlignment(QtCore.Qt.AlignCenter)
        self.PushButton_VoltageRead=QPushButton('读取')
        self.PushButton_VoltageRead.clicked.connect(self.ReadVoltage)
        self.hbox2 = QHBoxLayout()
        self.hbox2.addWidget(self.LineEdit_VoltageRead)
        self.hbox2.addWidget(QLabel('V'))
        self.hbox2.addWidget(self.PushButton_VoltageRead)
        self.FormLayout_VoltageControl.addRow('电压读取',self.hbox2)

        self.GropuBox_VoltageControl.setLayout(self.FormLayout_VoltageControl)
        return self.GropuBox_VoltageControl

        实际效果图:

        在设置输出电流/电压时,我们需要提取对应下拉中的内容,并按上面指令的格式进行发送:

    def SetCurrent(self):
        if self.SerialPort.isOpen():
            try:
                current = self.LineEdit_CurrentSet.text()
                if current:
                    channel_text = self.ComboBox_CurrentChannel.currentText()
                    channel_mapping = {"CH1": 1, "CH2": 2}
                    channel = channel_mapping[channel_text]
                    # 正确格式化字符串,并进行编码
                    data = f"ISET{channel}:{current}\r\n".encode('utf-8')
                    print(data)
                    # 确保使用的是正确的方法名
                    self.SerialPort.write(data)
                else:
                    QMessageBox.warning(self, "警告", "电流设置不能为空")
            except Exception as e:
                print(e)
                QMessageBox.critical(self, "错误", "设置电流值时出错")

    def SetVoltage(self):
        if self.SerialPort.isOpen():
            try:
                voltage = self.LineEdit_VoltageSet.text()
                if voltage:
                    channel_text = self.ComboBox_VoltageChannel.currentText()
                    channel_mapping = {"CH1": 1, "CH2": 2}
                    channel = channel_mapping[channel_text]
                    # 正确格式化字符串,并进行编码
                    data = f"VSET{channel}:{voltage}\r\n".encode('utf-8')
                    print(data)
                    # 确保使用的是正确的方法名
                    self.SerialPort.write(data)
                else:
                    QMessageBox.warning(self, "警告", "电压设置不能为空")
            except Exception as e:
                print(e)
                QMessageBox.critical(self, "错误", "设置电压值时出错")

        在读取电源实际输出电流/电压时,我们首先需要通过串口发送前文中的查询指令,同时开启串口接收进程,待接收到电源发过来对应的数据后,再将其处理后显示在对应的框中:

   def ReadCurrent(self):
        if self.SerialPort.isOpen():
            try:
                channel_text = self.ComboBox_CurrentChannel.currentText()
                channel_mapping = {"CH1": 1, "CH2": 2}
                channel = channel_mapping[channel_text]
                # 正确格式化字符串,并进行编码
                data = f"IOUT{channel}?\r\n".encode('utf-8')
                print(data)
                # 确保使用的是正确的方法名
                self.SerialPort.write(data)
                self.Thead.start()
                self.GPDThead.ReceiveCurrent_Start()
                self.SerialPort.clear()
                
            except Exception as e:
                print(e)
                QMessageBox.critical(self, "错误", "读取电流值时出错")

    def ReadCurrentProcess(self):
        if self.SerialPort.isOpen():
            try:
                data = self.SerialPort.readAll().data().decode('utf-8')
                if data:
                    print(data)
                    self.LineEdit_CurrentRead.clear()
                    self.LineEdit_CurrentRead.setText(data)
                    self.GPDThead.ReceiveCurrent_Stop()
                    self.Thead.quit()
            except Exception as e:
                print(e)
                QMessageBox.critical(self, "错误", "读取电流值时出错")


    def ReadVoltage(self):
        if self.SerialPort.isOpen():
            try:
                channel_text = self.ComboBox_VoltageChannel.currentText()
                channel_mapping = {"CH1": 1, "CH2": 2}
                channel = channel_mapping[channel_text]
                # 正确格式化字符串,并进行编码
                data = f"VOUT{channel}?\r\n".encode('utf-8')
                print(data)
                # 确保使用的是正确的方法名
                self.SerialPort.write(data)
                self.SerialPort.clear()
                self.Thead.start()
                self.GPDThead.ReceiveVoltage_Start()
            except Exception as e:
                print(e)
                QMessageBox.critical(self, "错误", "读取电压值时出错")

    def ReadVoltageProcess(self):
        if self.SerialPort.isOpen():
            try:
                data = self.SerialPort.readAll().data().decode('utf-8')
                if data:
                    print(data)
                    self.LineEdit_VoltageRead.clear()
                    self.LineEdit_VoltageRead.setText(data)
                    self.GPDThead.ReceiveVoltage_Stop()
                    self.Thead.quit()
            except Exception as e:
                print(e)
                QMessageBox.critical(self, "错误", "读取电压值时出错")

3、 定制功能——电流脉冲

        为了精确控制输出对应电流的时间,我们可以在程序上做一个简单的集成:

        如上图所示的界面实现代码示例:

    def CurrentPulse_ModeOne(self):
        self.GropuBox_CurrentPulse_ModeOne=QGroupBox('电流脉冲模式一')
        self.FormLayout_CurrentPulse_ModeOne=QFormLayout()

        self.LineEdit_PreheatTime=QLineEdit()
        self.LineEdit_PreheatTime.setAlignment(QtCore.Qt.AlignCenter)
        self.LineEdit_PreheatCurrent=QLineEdit()
        self.LineEdit_PreheatCurrent.setAlignment(QtCore.Qt.AlignCenter)
        self.hbox1 = QHBoxLayout()
        self.hbox1.addWidget(QLabel('预热时间:'))
        self.hbox1.addWidget(self.LineEdit_PreheatTime)
        self.hbox1.addWidget(QLabel('s'))
        self.hbox1.addWidget(QLabel('预热电流:'))
        self.hbox1.addWidget(self.LineEdit_PreheatCurrent)
        self.hbox1.addWidget(QLabel('A'))
        self.FormLayout_CurrentPulse_ModeOne.addRow('',self.hbox1)

        self.LineEdit_RestTime=QLineEdit()
        self.LineEdit_RestTime.setAlignment(QtCore.Qt.AlignCenter)
        self.hbox2 = QHBoxLayout()
        self.hbox2.addWidget(QLabel('休息时间:'))
        self.hbox2.addWidget(self.LineEdit_RestTime)
        self.hbox2.addWidget(QLabel('s'))
        self.FormLayout_CurrentPulse_ModeOne.addRow('',self.hbox2)


        self.LineEdit_WorkTime=QLineEdit()
        self.LineEdit_WorkTime.setAlignment(QtCore.Qt.AlignCenter)
        self.LineEdit_WorkCurrent=QLineEdit()
        self.LineEdit_WorkCurrent.setAlignment(QtCore.Qt.AlignCenter)
        self.hbox3 = QHBoxLayout()
        self.hbox3.addWidget(QLabel('工作时间:'))
        self.hbox3.addWidget(self.LineEdit_WorkTime)
        self.hbox3.addWidget(QLabel('s'))
        self.hbox3.addWidget(QLabel('工作电流:'))
        self.hbox3.addWidget(self.LineEdit_WorkCurrent)
        self.hbox3.addWidget(QLabel('A'))
        self.FormLayout_CurrentPulse_ModeOne.addRow('',self.hbox3)

        self.LineEdit_CircleTime=QLineEdit()
        self.LineEdit_CircleTime.setAlignment(QtCore.Qt.AlignCenter)
       
        self.hbox4 = QHBoxLayout()
        self.hbox4.addWidget(QLabel('循环次数:'))
        self.hbox4.addWidget(self.LineEdit_CircleTime)
        self.FormLayout_CurrentPulse_ModeOne.addRow('',self.hbox4)
        self.ComboBox_ChannelOne=QComboBox()
        self.ComboBox_ChannelOne.addItems(['CH1','CH2'])
       
        self.hbox5 = QHBoxLayout()
        self.hbox5.addWidget(QLabel('通道选择:'))
        self.hbox5.addWidget(self.ComboBox_ChannelOne)
        self.FormLayout_CurrentPulse_ModeOne.addRow('',self.hbox5)

        self.PushButton_CurrentPulse_ModeOne=QPushButton('开始')
        self.PushButton_CurrentPulse_ModeOne.clicked.connect(self.CurrentPulse_ModeOne_Init)
        self.PushButton_CurrentPulse_ModeOne.setCheckable(True)
        self.FormLayout_CurrentPulse_ModeOne.addRow('',self.PushButton_CurrentPulse_ModeOne)
        self.GropuBox_CurrentPulse_ModeOne.setLayout(self.FormLayout_CurrentPulse_ModeOne)
        return self.GropuBox_CurrentPulse_ModeOne

    def CurrentPulse_ModeTwo(self):
        self.GropuBox_CurrentPulse_ModeTwo=QGroupBox('电流脉冲模式二')
        self.FormLayout_CurrentPulse_ModeTwo=QFormLayout()

        self.LineEdit_InitialCurrent=QLineEdit()
        self.LineEdit_InitialCurrent.setAlignment(QtCore.Qt.AlignCenter)
        self.hbox1 = QHBoxLayout()
        self.hbox1.addWidget(QLabel('初始电流:'))
        self.hbox1.addWidget(self.LineEdit_InitialCurrent)
        self.hbox1.addWidget(QLabel('A'))
        self.FormLayout_CurrentPulse_ModeTwo.addRow('',self.hbox1)

        self.LineEdit_HeatRate=QLineEdit()
        self.LineEdit_HeatRate.setAlignment(QtCore.Qt.AlignCenter)
        self.hbox2 = QHBoxLayout()
        self.hbox2.addWidget(QLabel('升温速率:'))
        self.hbox2.addWidget(self.LineEdit_HeatRate)
        self.hbox2.addWidget(QLabel('A/s'))
        self.FormLayout_CurrentPulse_ModeTwo.addRow('',self.hbox2)

        self.LineEdit_EndCurrent=QLineEdit()
        self.LineEdit_EndCurrent.setAlignment(QtCore.Qt.AlignCenter)
        self.hbox3 = QHBoxLayout()
        self.hbox3.addWidget(QLabel('结束电流:'))
        self.hbox3.addWidget(self.LineEdit_EndCurrent)
        self.hbox3.addWidget(QLabel('A'))
        self.FormLayout_CurrentPulse_ModeTwo.addRow('',self.hbox3)

        self.ComboBox_ChannelTwo=QComboBox()
        self.ComboBox_ChannelTwo.addItems(['CH1','CH2'])
        self.PushButton_CurrentPulse_ModeTwo=QPushButton('开始')
        self.PushButton_CurrentPulse_ModeTwo.clicked.connect(self.ModeTwo_Init)
        self.PushButton_CurrentPulse_ModeTwo.setCheckable(True)
        self.hbox4 = QHBoxLayout()
        self.hbox4.addWidget(QLabel('通道选择:'))
        self.hbox4.addWidget(self.ComboBox_ChannelTwo)
        self.hbox4.addWidget(self.PushButton_CurrentPulse_ModeTwo)
        self.FormLayout_CurrentPulse_ModeTwo.addRow('',self.hbox4)
       
        
        self.FormLayout_CurrentPulse_ModeTwo.addRow('',self.PushButton_CurrentPulse_ModeTwo)
        self.GropuBox_CurrentPulse_ModeTwo.setLayout(self.FormLayout_CurrentPulse_ModeTwo)
        return self.GropuBox_CurrentPulse_ModeTwo

        对于上图所示功能,我们可以通过一个定时进程定时向串口发送输出电流设置指令实现。

    def ModeTwo_Init(self):
        if self.SerialPort.isOpen() and self.PushButton_CurrentPulse_ModeTwo.isChecked():
            try:
                self.current=float(self.LineEdit_InitialCurrent.text())
                self.Thead.start()
                self.GPDThead.ModeTwo_Start()
                self.GPDThead.ReceiveData_Start()
                self.SerialPort.clear()
                self.PushButton_CurrentPulse_ModeTwo.setText('停止')
                self.PushButton_CurrentPulse_ModeTwo.setStyleSheet("background-color: red; color: black;")
            except Exception as e:
                print(e)
                QMessageBox.critical(self, "错误", "模式二启动失败")
        else:
            self.Thead.quit()
            self.GPDThead.ModeTwo_Stop()
            self.GPDThead.ReceiveData_Stop()
            self.PushButton_CurrentPulse_ModeTwo.setText('开始')
            self.PushButton_CurrentPulse_ModeTwo.setStyleSheet("background-color: white; color: black;")

    def ModeTwo_Send(self):
        try:
            heat_rate = float(self.LineEdit_HeatRate.text())
            end_current = float(self.LineEdit_EndCurrent.text())
            if self.current+heat_rate<end_current:
                self.current+=heat_rate
            else:
                self.current=end_current
            channel_text = self.ComboBox_ChannelTwo.currentText()
            channel_mapping = {"CH1": 1, "CH2": 2}
            channel = channel_mapping[channel_text]
            data = f"ISET{channel}:{self.current}\r\n".encode('utf-8')
            self.SerialPort.write(data)
        except Exception as e:
            print(e)

        这里我们给出了电流脉冲模式二的部分代码,模式一的代码也同理。

4、实时输出数据图绘制

        在上面的基础上,我们虽然定时发送了输出控制指令,但我们不知道电源的实时输出情况,所以在这里还需要把实时输出情况绘制出来。同时,我们知道可以通过发送查询得知实时输出。于是,在接收到上一个数据后在坐标轴上标点连线,再次发送查询命令,可画出电源实时输出折线图。

class ChartView(QChartView,QChart):
    def __init__(self, *args, **kwargs):
        super(ChartView, self).__init__(*args, **kwargs)
        self.resize(800, 600)
        self.setRenderHint(QPainter.Antialiasing)  # 抗锯齿
        self.chart_init()
        #def timer_init(self):
        #使用QTimer,2秒触发一次,更新数据
        #self.timer = QTimer(self)
        #self.timer.timeout.connect(self.drawLine)
        #self.timer.start(2000)
    def chart_init(self):
        self.chart = QChart()
        self.series = QSplineSeries()
        #设置曲线名称
        self.series.setName("实时数据")
        #把曲线添加到QChart的实例中
        self.chart.addSeries(self.series)
        #声明并初始化X轴,Y轴
        self.dtaxisX = QDateTimeAxis()
        self.vlaxisY = QValueAxis()
        #设置坐标轴显示范围
        self.dtaxisX.setMin(QDateTime.currentDateTime().addSecs(-300*1))
        self.dtaxisX.setMax(QDateTime.currentDateTime().addSecs(0))
        self.vlaxisY.setMin(0)
        self.vlaxisY.setMax(10)
        #设置X轴时间样式
        self.dtaxisX.setFormat("MM月dd hh:mm:ss")
        #设置坐标轴上的格点
        self.dtaxisX.setTickCount(6)
        self.vlaxisY.setTickCount(11)
        #设置坐标轴名称
        self.dtaxisX.setTitleText("时间")
        self.vlaxisY.setTitleText("量程")
        #设置网格不显示
        self.vlaxisY.setGridLineVisible(False)
        #把坐标轴添加到chart中
        self.chart.addAxis(self.dtaxisX,Qt.AlignBottom)
        self.chart.addAxis(self.vlaxisY,Qt.AlignLeft)
        #把曲线关联到坐标轴
        self.series.attachAxis(self.dtaxisX)
        self.series.attachAxis(self.vlaxisY)

        self.setChart(self.chart)
    def drawLine(self):
        #获取当前时间
        bjtime = QDateTime.currentDateTime()
        #更新X轴坐标
        self.dtaxisX.setMin(QDateTime.currentDateTime().addSecs(-300*1))
        self.dtaxisX.setMax(QDateTime.currentDateTime().addSecs(0))
        #当曲线上的点超出X轴的范围时,移除最早的点
        if(self.series.count()>149):
            self.series.removePoints(0,self.series.count()-149)
        #产生随即数
        yint = random.randint(0,1500)
        #添加数据到曲线末端
        self.series.append(bjtime.toMSecsSinceEpoch(),yint)

        界面图:

三、实际效果演示

        程序测试完美运行,功能全实现,搞定!

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Pyside6和PyQt6都是Python编程语言中用于创建GUI应用程序的工具包。它们都是基于Qt框架构建的,因此具有相似的功能和API。 以下是关于使用Pyside6/PyQt6进行快速开发和实战的一些提示: 1. 学习Qt框架:Qt框架是创建GUI应用程序的基础。学习Qt框架可以帮助你了解Pyside6和PyQt6的工作原理,以及如何使用它们创建GUI应用程序。 2. 学习Python编程语言:Pyside6和PyQt6都是Python编程语言的库。因此,熟悉Python编程语言可以帮助你更好地使用这些库。 3. 使用Qt Designer:Qt Designer是一个可视化工具,可以帮助你轻松创建GUI应用程序的UI。你可以使用Qt Designer创建UI,并将其导入到Pyside6/PyQt6项目中。 4. 学习信号和槽:信号和槽是Pyside6/PyQt6中的重要概念。信号是一个事件,例如按钮单击或文本更改,而槽是响应这些事件的函数。学习如何使用信号和槽可以帮助你创建响应用户操作的GUI应用程序。 5. 阅读文档和示例代码:Pyside6和PyQt6都有详细的文档和示例代码。阅读这些文档和示例代码可以帮助你了解如何使用库中的不同功能和API,并为你的项目提供灵感。 6. 加入社区:Pyside6和PyQt6有活跃的社区和论坛。加入这些社区可以帮助你与其他开发人员交流经验,并得到解决问题的帮助。 总之,使用Pyside6和PyQt6进行快速开发和实战需要学习Qt框架、Python编程语言、Qt Designer、信号和槽等知识,并阅读文档和示例代码。加入社区可以帮助你更好地了解和使用这些库。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值