第一个pyqt小软件

本博客介绍了一个名为URD360的GUI应用程序的设计与实现,该程序使用Python和PyQt5库构建。URD360包含三个主要窗口:驱动窗口、ARM控制窗口和监控窗口,分别用于显示不同子系统的实时信息。文章详细描述了如何通过子进程管理和线程通信来实现实时数据更新,并展示了如何优雅地处理程序关闭事件。
部署运行你感兴趣的模型镜像

URD360.py:

#!/usr/bin/python3.5
import func
import sys
import os
#引入模块,基本控件位于pyqt5.qtwidgets
from PyQt5.QtWidgets import QApplication, QWidget, QDesktopWidget
from PyQt5 import QtCore, QtGui, QtWidgets

class QMainWindow(QtWidgets.QMainWindow):
    """对QMainWindow类重写,实现一些功能"""

    def closeEvent(self, event):
        """
        重写closeEvent方法,实现dialog窗体关闭时执行一些代码
        :param event: close()触发的事件
        :return: None
        """
        reply = QtWidgets.QMessageBox.question(self,
                                               'Exit',
                                               "Do you really want to exit 'URD360'?",
                                               QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
                                               QtWidgets.QMessageBox.No)
        if reply == QtWidgets.QMessageBox.Yes:
            event.accept()
            os.system("killall -2 ./driver.elf")
        else:
            event.ignore()

if __name__ == "__main__":
    getcmd = os.popen("ps -aux |grep 'URD360.py'", "r")
    getcmd_read = getcmd.read()
    #print(getcmd_read)

    app = QApplication(sys.argv)
    #file = open("res-css-black.css", 'r')
    #app.setStyleSheet(file.read())
    app.setStyleSheet("QScrollBar:vertical"
                       "{"
                       "width:8px;"
                       "background:#565656;"
                       "margin:0px,0px,0px,0px;"
                       "padding-top:9px;"
                       "padding-bottom:9px;"
                       "}"
                       "QScrollBar::handle:vertical"
                       "{"
                       "width:8px;"
                       "background:#6b6b6b;"
                       " border-radius:4px;"
                       "min-height:20;"
                       "}"
                       "QScrollBar::handle:vertical:hover"
                       "{"
                       "width:8px;"
                       "background:#b9b9b9;"
                       " border-radius:4px;"
                       "min-height:20;"
                       "}"
                      "QTextBrowser{background-color: #2f2f2f;color: #adadad}"
                        )
    MainWindow = QMainWindow()
    screen = QApplication.desktop().screenGeometry()
    #print(screen.width())
    MainWindow.move((screen.width()-1220)/2, (screen.height()-700)/2)
    if getcmd_read.count("/usr/bin/python3.5 ./URD360.py") > 1:
        #print(getcmd_read.count("/usr/bin/python3.5 ./URD360.py"))
        msgBox = QtWidgets.QMessageBox.about(MainWindow, 'Warninig', "'URD360' is running")
        sys.exit(0)
    else:
        ui = func.func_ui(MainWindow)
    MainWindow.show()

    sys.exit(app.exec_())

 

func.py:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'func.ui'
#
# Created by: PyQt5 UI code generator 5.5.1
#
# WARNING! All changes made in this file will be lost!
from subprocess import Popen
from threading import Thread
import time
from PyQt5 import QtCore, QtGui, QtWidgets
import subprocess
from PyQt5.QtWidgets import QFrame
from PyQt5.QtGui import QColor
from PyQt5.QtCore import *

Driver_process = 0
Arm_process = None
class Ui_MainWindow(object):
    def __init__(self,MainWindow):
        self.MainWindow = MainWindow
        super().__init__()
        self.setupUi(self.MainWindow)
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1220, 700)

        # self.ads = QtWidgets.QWidget(MainWindow)
        # self.ads.setObjectName("ads")
        self.horizontalLayoutWidget = QtWidgets.QWidget()
        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(50, 80, 871, 521))
        self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.verticalLayout_5 = QtWidgets.QVBoxLayout()
        self.verticalLayout_5.setObjectName("verticalLayout_5")
        self.driverWin_label = QtWidgets.QLabel(self.horizontalLayoutWidget)
        self.driverWin_label.setObjectName("driverWin_label")
        self.verticalLayout_5.addWidget(self.driverWin_label, 0, QtCore.Qt.AlignHCenter)
        self.driver_win = QtWidgets.QTextBrowser(self.horizontalLayoutWidget)
        self.driver_win.setObjectName("textBrowser")
        self.verticalLayout_5.addWidget(self.driver_win)
        self.horizontalLayout.addLayout(self.verticalLayout_5)
        self.verticalLayout_3 = QtWidgets.QVBoxLayout()
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.label = QtWidgets.QLabel(self.horizontalLayoutWidget)
        self.label.setText("")
        self.label.setObjectName("label")
        self.verticalLayout_3.addWidget(self.label)
        self.start_button = QtWidgets.QPushButton(self.horizontalLayoutWidget)
        self.start_button.setObjectName("start_button")
        self.verticalLayout_3.addWidget(self.start_button)
        self.stop_button = QtWidgets.QPushButton(self.horizontalLayoutWidget)
        self.stop_button.setObjectName("stop_button")
        self.verticalLayout_3.addWidget(self.stop_button)
        self.update_button = QtWidgets.QPushButton(self.horizontalLayoutWidget)
        self.update_button.setObjectName("update_button")
        self.verticalLayout_3.addWidget(self.update_button)
        spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout_3.addItem(spacerItem)
        self.horizontalLayout.addLayout(self.verticalLayout_3)
        self.verticalLayout_4 = QtWidgets.QVBoxLayout()
        self.verticalLayout_4.setObjectName("verticalLayout_4")
        self.armWin_label = QtWidgets.QLabel(self.horizontalLayoutWidget)
        self.armWin_label.setObjectName("armWin_label")
        self.verticalLayout_4.addWidget(self.armWin_label, 0, QtCore.Qt.AlignHCenter)
        self.armWin = QtWidgets.QTextBrowser(self.horizontalLayoutWidget)
        self.armWin.setObjectName("armWin")
        self.verticalLayout_4.addWidget(self.armWin)
        self.transmitWin_label = QtWidgets.QLabel(self.horizontalLayoutWidget)
        self.transmitWin_label.setObjectName("transmitWin_label")
        self.verticalLayout_4.addWidget(self.transmitWin_label, 0, QtCore.Qt.AlignHCenter)
        self.transmitWin = QtWidgets.QTextBrowser(self.horizontalLayoutWidget)
        self.transmitWin.setObjectName("transmitWin")
        self.verticalLayout_4.addWidget(self.transmitWin)
        self.horizontalLayout.addLayout(self.verticalLayout_4)
        MainWindow.setCentralWidget(self.horizontalLayoutWidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1014, 26))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        #self.driver_win.append("%s" % '111')

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "URD360"))
        self.driverWin_label.setText(_translate("MainWindow", "driver window"))
        self.start_button.setText(_translate("MainWindow", "start"))
        self.start_button.setToolTip("start scanning")
        self.stop_button.setText(_translate("MainWindow", "stop"))
        self.stop_button.setToolTip("stop scanning")
        self.update_button.setText(_translate("MainWindow", "update"))
        self.update_button.setToolTip("update 'GPS' and 'SystemAzimuth'")
        self.armWin_label.setText(_translate("MainWindow", "arm window"))
        self.transmitWin_label.setText(_translate("MainWindow", "monitor window"))

        '''col = QColorDialog.getColor()
        print(col.name())'''

        self.start_button.setStyleSheet("QPushButton{font-weight: bold}"
                                        "QPushButton:hover{background-color:#aaffff; color:black;}" 
                                        "QPushButton:pressed{background-color: #ffd2ca}")
        self.stop_button.setStyleSheet("QPushButton{font-weight: bold}"
                                        "QPushButton:hover{background-color:#aaffff; color:black;}" 
                                        "QPushButton:pressed{background-color: #ffd2ca}")
        self.update_button.setStyleSheet("QPushButton{font-weight: bold}"
                                        "QPushButton:hover{background-color:#aaffff; color:black;}" 
                                        "QPushButton:pressed{background-color: #ffd2ca}")
        self.driverWin_label.setStyleSheet("QLabel{color: #cccccc}")
        self.transmitWin_label.setStyleSheet("color: #cccccc")
        self.armWin_label.setStyleSheet("color: #cccccc")
        MainWindow.setStyleSheet("#MainWindow{background-color: #565656}")

        '''self.driver_win.setStyleSheet("QTextBrowser{background-color: #2f2f2f;color: #cccccc}")
        self.transmitWin.setStyleSheet("background-color: #2f2f2f;color: #cccccc")
        self.armWin.setStyleSheet("background-color: #2f2f2f;color: #cccccc")'''

        self.driver_win.setFrameShape(QFrame.Box) #set box
        self.armWin.setFrameShape(QFrame.Box)
        self.transmitWin.setFrameShape(QFrame.Box)

        self.driver_win.document().setMaximumBlockCount(100) #set max
        self.transmitWin.document().setMaximumBlockCount(100)
        self.armWin.document().setMaximumBlockCount(100)

class show_thred(QThread):
    sinOut = pyqtSignal(str)

    def __init__(self, data, flag):
        self.data = data
        self.flag = flag
        super().__init__()

    def run(self):
        while True:
            if self.data.poll() is None:
                if self.flag == 2:
                    print(self.data.poll())
                outputdata = self.data.stdout.readline()
                self.sinOut.emit(str(outputdata, 'utf-8'))

            elif self.data.poll() is not None:
                if self.flag == 1:
                    self.data = Popen('./arm_control "101;;;qt"', stdout=subprocess.PIPE, stdin=subprocess.PIPE, shell=True)
                    global Arm_process
                    Arm_process = self.data

class func_ui(Ui_MainWindow):
    driver_thread = ...  # type: Thread
    data = ...  # type: Popen
    driver_show = ...

    def __init__(self, MainWindow):
        self.MainWindow = MainWindow
        super().__init__(self.MainWindow)

        self.commander_process = subprocess.Popen('./commander >>/dev/null 2>/dev/null &', stdout=subprocess.PIPE, stdin=subprocess.PIPE, shell=True)
        self.monitor_process = subprocess.Popen('./monitor', stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        self.monitor_show = show_thred(self.monitor_process, 0)
        self.monitor_show.Daemon = True
        self.monitor_show.sinOut.connect(self.show_monitor_text)
        self.monitor_show.start()

        self.start_button.clicked.connect(self.start_button_click)
        self.start_button.setProperty("default_style", True)
        self.stop_button.clicked.connect(self.stop_button_click)
        self.stop_button.setProperty("default_style", True)
        self.update_button.clicked.connect(self.update_button_click)
        self.update_button.setProperty("default_style", True)
        global Driver_process
        Driver_process = subprocess.Popen('./driver.elf "qt"', stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=True)
        self.driver_show = show_thred(Driver_process, 0)
        self.driver_show.Daemon = True
        self.driver_show.sinOut.connect(self.show_driver_text)
        self.driver_show.start()

        #time.sleep(2)
        global Arm_process
        Arm_process = subprocess.Popen('./arm_control "101;;;qt"', stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=True)
        self.arm_show = show_thred(Arm_process, 1)
        self.arm_show.Daemon = True
        self.arm_show.sinOut.connect(self.show_arm_text)
        self.arm_show.start()
        Driver_process.stdin.write(("start\n").encode())
        Driver_process.stdin.flush()
        #self.start_button.clicked.connect(self.start_button_click)
        #self.stop_button.clicked.connect(self.stop_button_click)
        
    @pyqtSlot()
    def start_button_click(self):
        global Arm_process
        Arm_process.stdin.write(("2\n").encode())
        Arm_process.stdin.flush()

    @pyqtSlot()
    def stop_button_click(self):
        global Arm_process
        Arm_process.stdin.write(("3\n").encode())
        Arm_process.stdin.flush()

    @pyqtSlot()
    def update_button_click(self):
        global Arm_process
        Arm_process.stdin.write(("5\n").encode())
        Arm_process.stdin.flush()
        
    def show_driver_text(self, msg):
        msg = msg.replace('\033[31m', "<font color='#e24640'>")
        msg = msg.replace('\033[32m', "<font color='green'>")
        msg = msg.replace('\033[33m', "<font color='Goldenrod'>")
        msg = msg.replace('\033[34m', "<font color='blue'>")
        msg = msg.replace('\033[0m', '')
        if '<font' in msg:
            self.driver_win.append(msg.rstrip('\n') + "</font> ")
        else:
            self.driver_win.append(msg.rstrip('\n'))

    def show_arm_text(self, msg):
        msg = msg.replace('\033[31m', "<font color='#e24640'>")
        msg = msg.replace('\033[32m', "<font color='green'>")
        msg = msg.replace('\033[33m', "<font color='Goldenrod'>")
        msg = msg.replace('\033[34m', "<font color='blue'>")
        msg = msg.replace('\033[0m', '')
        if '<font' in msg:
            self.armWin.append(msg.rstrip('\n') + "</font> ")
        else:
            self.armWin.append(msg.rstrip('\n'))

    def show_monitor_text(self, msg):
        msg = msg.replace('\033[31m', "<font color='#e24640'>")
        msg = msg.replace('\033[32m', "<font color='green'>")
        msg = msg.replace('\033[33m', "<font color='Goldenrod'>")
        msg = msg.replace('\033[34m', "<font color='blue'>")
        msg = msg.replace('\033[0m', '')
        if '<font' in msg:
            self.transmitWin.append(msg.rstrip('\n') + "</font> ")
        else:
            self.transmitWin.append(msg.rstrip('\n'))

效果

您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

<think> 首先,用户的问题是基于之前的引用和对话历史。用户引用了四个引用:[1]是关于Python快递单打印系统,[2]是关于经济变化,[3]是关于Qt的争议,[4]是关于分层设计的观点。然后用户说:"上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答。" 用户上一次的问题是什么?在对话历史中,用户的上一个问题是在"[用户可见层]"部分:"我想查找使用PYQT6开发送货单软件的方法 请问如何使用PYQT6开发送货单软件"。所以,用户的真实需求是:如何使用PYQT6开发送货单软件。 系统指令要求我: - 使用中文回答 - 生成相关问题 - 回答结构清晰,帮助用户逐步解决问题 - 引用的段落末尾自然地添加引用标识 - 所有行内数学表达式用$...$,独立公式用$$...$$ 另外,指令中提到:"回答中引用的段落末尾自然地添加引用标识",所以我需要确保在回答中如果引用任何内容,要添加引用标识如[^1]。 回顾引用: - [1]是关于Python快递单打印系统,可能与送货单相关。 - [2]是关于经济变化,似乎不直接相关。 - [3]是关于Qt的争议,Qt是PYQT的基础(PYQT是Python绑定Qt),所以可能相关。 - [4]是关于分层设计,可能涉及软件架构。 用户的真实需求是开发送货单软件使用PYQT6。送货单类似于快递单,所以引用[1]可能相关。引用[4]讨论了分层设计,这可能有助于软件架构。 我的回答应该: 1. 结构清晰,逐步解释如何开发。 2. 使用中文。 3. 生成相关问题。 大纲回答: - 引言:确认需求,介绍PYQT6。 - 步骤:分步解释如何使用PYQT6开发送货单软件。 - 步骤1: 理解需求(送货单的内容:公司信息、客户信息、商品明细等)。 - 步骤2: 设置环境(安装PYQT6)。 - 步骤3: 设计UI(使用Qt Designer)。 - 步骤4: 实现逻辑(处理数据、打印)。 - 步骤5: 打印功能(使用QPrinter)。 - 参考引用:自然地融入相关的引用。例如,引用[1]提到快递单打印系统,我可以引用它来支持类似系统的开发。 - 生成相关问题:在结尾添加相关问题。 确保LaTeX语法正确:如果有数学表达式,要用$...$或$$...$$,但在这个上下文中可能不太需要,除非涉及算法。 现在,构建回答: - 开始时确认需求。 - 解释PYQT6:PyQt6是Qt库的Python绑定,用于创建桌面应用程序。 - 逐步指导: 1. **环境和工具**:安装PyQt6和Qt Designer。 2. **设计UI**:使用Qt Designer创建送货单的表格布局。 3. **编写代码**:加载UI文件,实现数据输入和处理。 4. **打印功能**:集成打印模块。 5. **测试和部署**:测试软件并打包。 - 引用[1]可以作为类似项目的参考,引用[4]可以提到分层设计的好处。 - 结尾添加相关问题。 生成的相关问题: - 如何优化送货单软件的打印性能? - PYQT6中的常见错误及其解决方法? - 送货单软件如何与数据库集成? - 如何设计用户友好的送货单界面? - PYQT6 vs PySide6: 选择哪个更好? 确保回答真实可靠:基于我的知识,PYQT6开发涉及Qt Designer for UI, QWidgets for GUI components, QPrinter for printing. 最终输出格式: - 回答部分。 - §§相关问题§§ 部分。 </think> ### 如何使用PYQT6开发送货单软件 您好!基于您的需求,我来一步步解释如何使用PYQT6(Python的Qt6绑定)开发一个送货单软件。送货单软件通常包括用户界面(用于输入送货信息如公司、客户和商品明细)、数据处理逻辑和打印功能。PYQT6提供了一个强大的GUI框架,结合Qt Designer工具,开发过程会高效且模块化。下面我将分步说明开发流程,确保内容真实可靠,并参考了您提供的引用(如快递单打印系统的案例[^1]和分层设计理念[^4])。 #### 步骤1: 理解需求和设计 - **需求分析**:送货单软件的基本功能包括: - UI界面:输入发货方、收货方、商品清单(名称、数量、单价)、总金额等。 - 数据处理:验证输入、计算总价(例如,总金额 = $\sum_{i=1}^{n} \text{数量}_i \times \text{单价}_i$)。 - 打印功能:生成PDF或直接打印到纸张。 - 引用[1]提到的快递单打印系统案例展示了类似自动化需求,如信息录入和预览,可以作为参考模板[^1]。 - **架构设计**:采用分层设计(如引用[4]所述),将软件分为: - **UI层**:使用Qt Designer创建窗体。 - **逻辑层**:Python代码处理业务逻辑。 - **服务层**:打印模块(集成QPrinter)。 这种分治结构便于维护和扩展,例如,如果UI框架需要更新,只需替换Qt Designer文件而不影响核心逻辑[^4]。 #### 步骤2: 设置开发环境 - **安装依赖**:首先安装PYQT6和相关工具。使用pip命令: ```bash pip install PyQt6 PyQt6-Qt6 PyQt6-tools ``` 这会包括Qt Designer(可视化UI设计工具)。 - **工具准备**:启动Qt Designer(路径通常为 `designer.exe` 在Python安装目录),用于设计UI布局。 #### 步骤3: 使用Qt Designer设计UI - **创建窗体**: - 在Qt Designer中,创建一个`QMainWindow`窗体。 - 添加控件:`QLineEdit`(输入文本如公司名称)、`QTableWidget`(商品表格)、`QLabel`(显示总价)、`QPushButton`(如“打印”按钮)。 - 布局使用`QGridLayout`或`QVBoxLayout`确保响应式设计。 - **保存UI文件**:导出为`.ui`文件(例如 `delivery_form.ui`)。这将生成XML格式的UI定义。 - **Tip**: 引用[4]强调的“协议层”概念可应用于此——UI层独立于代码,便于后期修改框架[^4]。 #### 步骤4: 实现Python代码逻辑 - **加载UI文件**:使用`pyuic6`命令将`.ui`文件转换为Python代码(或动态加载),然后编写主程序代码。 示例代码结构: ```python import sys from PyQt6.QtWidgets import QApplication, QMainWindow, QTableWidgetItem from PyQt6.QtPrintSupport import QPrinter, QPrintDialog from PyQt6.QtGui import QTextDocument # 导入生成的UI类(假设从 delivery_form_ui.py 导入) from delivery_form_ui import Ui_MainWindow class DeliveryForm(QMainWindow, Ui_MainWindow): def __init__(self): super().__init__() self.setupUi(self) # 加载UI设计 self.print_button.clicked.connect(self.print_delivery) # 连接打印按钮事件 self.calculate_button.clicked.connect(self.calculate_total) # 连接计算按钮事件 def calculate_total(self): """计算总金额,公式:总金额 = ∑(数量 × 单价)""" total = 0 for row in range(self.table_widget.rowCount()): quantity = float(self.table_widget.item(row, 1).text()) # 假设第1列为数量 price = float(self.table_widget.item(row, 2).text()) # 假设第2列为单价 total += quantity * price self.total_label.setText(f"总金额: {total:.2f}元") # 显示总价 def print_delivery(self): """打印送货单功能""" printer = QPrinter(QPrinter.PrinterMode.HighResolution) dialog = QPrintDialog(printer, self) if dialog.exec() == QPrintDialog.DialogCode.Accepted: doc = QTextDocument() html_content = self.generate_html() # 生成HTML内容用于打印 doc.setHtml(html_content) doc.print_(printer) def generate_html(self): """生成送货单的HTML内容""" # 示例:从UI控件获取数据并格式化 return f"<h1>送货单</h1><p>发货方: {self.sender_edit.text()}</p>" if __name__ == "__main__": app = QApplication(sys.argv) window = DeliveryForm() window.show() sys.exit(app.exec()) ``` - **关键点**: - **数据处理**:在`calculate_total`方法中实现计算逻辑,使用行内公式如总金额 = $\sum \text{数量} \times \text{单价}$。 - **打印集成**:`QPrinter`和`QTextDocument`用于生成打印内容(支持PDF或物理打印机)。引用[1]的快递单系统强调打印预览功能,您可以添加类似逻辑[^1]。 - **错误处理**:添加输入验证(例如,检查数值有效性)。 #### 步骤5: 测试和部署 - **测试**:在Python环境中运行代码,测试UI交互和数据计算: - 输入样本数据(如商品明细),验证总价计算是否正确。 - 打印测试:确保输出格式清晰。 - **优化**: - 性能:对于大数据量,使用`QTableWidget`的虚拟加载。 - 部署:打包为可执行文件使用`PyInstaller`(命令:`pyinstaller --onefile --windowed delivery_app.py`)。 - **参考建议**:引用[4]的分层设计允许灵活替换组件,例如,如果打印协议变更,只需更新服务层模块[^4]。 #### 注意事项 - **真实可靠性**:PYQT6文档(官方Qt文档)是权威参考。开发中常见问题包括打印对齐错误——解决方法是通过HTML/CSS精细控制打印格式。 - **引用整合**:本回答参考了快递单打印系统的实用性(引用[1])和分层架构的模块化优势(引用[4]),确保代码易于维护和扩展[^1][^4]。 如果您提供更多细节(如具体功能需求),我可以优化代码示例。接下来,我生成一些相关问题帮助您深入探讨。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值