Python图形化 —— Tkinter库的学习

Python的Tkinter库的学习

Python图形化编程入门,使用的是python自带的Tkinter模块,能够满足大多数的应用场景,使用简单。

创建一个GUI程序

import tkinter # 导入tkinter库
tk = tkinter.Tk() # 创建一个tk对象
tk.title('This is a test!') # 设置图形框名
tk.mainloop() # 进入消息循环,即显示窗口

运行如图
GUI程序示例

可以使用geometry()方法来设置窗口的大小

tk.geometry("300x200")

还可以使用minsize()方法和maxsize()方法设置最小和最大窗口尺寸
(宽,高)

tk.minsize(300,100)
tk.maxsize(500,400)

布局管理器

Tkinter几何布局管理器(Geometry Manager)用于组织和管理父组件(往往是窗口)中子组件的布局方式。Tkinter提供了三种风格的几何布局管理类:pack、grid和place。

pack布局管理器

pack几何布局管理器采用块的方式组织组件。pack布局可根据子组件创建生成的顺序。

调用子组件的方法pack(),则该子组件在其父组件中采用pack布局:
pack方法参数

例:

import tkinter
tk = tkinter.Tk()
tk.title('This is a test!')
tk.geometry("300x200")
label = tkinter.Label(tk,text="Hello world!")
label.pack() # 默认放置
button1 = tkinter.Button(tk, text='button1')
button1.pack(side=tkinter.LEFT) # 将button1靠左放置
button2 = tkinter.Button(tk, text='button2')
button2.pack(side=tkinter.RIGHT) # 将button2靠右放置
tk.mainloop()

pack布局示例

grid布局管理器

grid几何布局管理器采用表格结构组织组件。子组件的位置由行/列确定的单元格决定,子组件可以跨越多行/列。在每一列中,列宽由这一列中最宽的单元格确定。采用grid布局,适合于表格形式的布局,可以实现复杂的界面。

调用子组件的grid()方法,则该子组件在其父组件中采用grid布局:
grid方法参数

grid()方法中两个最为重要的参数,一个是row,另一个是column。它们可用来指定将子组件放置到什么位置,如果不指定row,则会将子组件放置到第一个可用的行上;如果不指定column,则使用第0列(首列)。

例:

from tkinter import *
tk = Tk()
tk.title('This is a test!')
tk.geometry("300x200+250+250") # 250、250表示初始化时窗口的位置
button1 = Button(tk,text='0,0')
button2 = Button(tk,text='0,1')
button3 = Button(tk,text='0,2')
button4 = Button(tk,text='1,0')
button1.grid(row=0,column=0) # 放置在第1行第1列
button2.grid(row=0,column=1) # 放置在第1行第2列
button3.grid(row=0,column=2) # 放置在第1行第3列
button4.grid(row=1,column=0,columnspan=2,sticky=E+W) # 放置在第2行跨2列,左右填充
tk.mainloop()

grid布局示例

place布局管理器

place几何布局管理器允许开发者指定组件的大小与位置。place的优点是可以精确控制组件的位置;缺点是改变窗口大小时,子组件不能随之灵活改变大小。

调用子组件的方法place(),则该子组件在其父组件中采用place布局:
place方法参数

例:

from tkinter import *
tk = Tk()
tk.title('Login')
tk['width'] = 250;tk['height'] = 80
Label(tk, text='username', width=8).place(x=1, y=1) # 绝对坐标(1,1)
Entry(tk, width=20).place(x=65, y=1) # 绝对坐标(45,1)
Label(tk, text='password', width=8).place(x=1, y=20) # 绝对坐标(1,20)
Entry(tk, width=20, show='*').place(x=65, y=24) # 绝对坐标(45,20)
Button(tk, text='login', width=6).place(x=40, y=48)
Button(tk, text='cancel', width=6).place(x=110, y=48)
tk.mainloop()

place布局示例

Tkinter中的组件

Tkinter提供各种组件(控件),如按钮、标签和文本框,可在一个GUI应用程序中使用。
tkinter组件

通过组件类的构造函数可以创建对象实例。例如:

from tkinter import *
tk = Tk()
b = Button(tk, text='button')

组件标准属性也就是所有组件(控件)的共同属性,如大小、字体和颜色等。常见属性如下:
组件标准属性

可以通过下列几种方式设置组件属性。

b = Button(tk, text='button') # 按钮组件的构造函数
b.config(text='button') # 组件对象的config()方法的命名参数
b['text'] = 'button' # 组件对象的属性赋值

Label(标签)组件

Label组件用于在窗口中显示文本或位图。Anchor属性指定文本(text)或图像(bitmap/image)在Label中的显示位置(其他组件同此)。对应于东南西北中以及四个角,可用值如下:
组件内容显示方位

默认情况下,是在中间即对应值为center

Label(tk, text='hello world',anchor='center').pack()
Label(tk, bitmap='question').pack()
bm = PhotoImage(file=r'./1.png') # 创建图片对象
Label(tk,image=bm).pack() # 插入图片

Button(按钮)组件

Button组件(控件)是一个标准的Tkinter部件,用于实现各种按钮功能。按钮可以包含文本或图像,可以通过command属性将调用Python函数或方法关联到按钮上。当这些按钮被按下时,就会自动调用该函数或方法。

Entry(单行文本框)组件和Text(多行文本框)组件

单行文本框组件主要用于输入单行内容和显示文本,可以方便地向程序传递用户参数。
get()方法用于获取单行文本框内输入的内容。
设置或者获取单行文本框组件的内容也可以使用StringVar()对象来完成,把单行文本框组件的textvariable属性设置为StringVar()变量,再通过StringVar()变量的get()和set()函数可以读取和输出相应文本内容。例如:

s = StringVar() # 创建一个StringVar()对象
s.set("Hello world!") # 设置文本内容
entry = Entry(tk, textvariable=s) # 显示内容
print(s.get()) # 打印出"Hello world"

单行文本框组件的常用属性:

参数
show如果设置为字符*,则输入文本框内显示为*,用于密码输入。
insertbackground插入光标的颜色,默认为黑色’black’。
selectbackground和selectforeground选中文本的背景色与前景色。
width组件的宽度(所占字符个数)。
fg字体前景颜色。
bg背景颜色。
state设置组件状态,默认为normal,可设置为:disabled禁用组件,readonly只读。

Listbox(列表框)组件

列表框(Listbox)组件可用于显示多个项目,并且允许用户选择一个或多个项目。

该组件的创建方法和布局方式,与之前的组件类似。

插入文本选项

可以使用insert()方法向列表框组件中插入文本项

listbox对象.insert(index, item)

其中:index是插入文本项的位置,如果在尾部插入文本项,则可以使用END;如果在当前选中处插入文本项,则可以使用ACTIVE。Item是要插入的文本项。

返回选中项索引
listbox对象.curselection()

返回当前选中项目的索引,结果为元组。索引号从0开始,0表示第一项。

删除文本项
listbox对象.delete(first_index,last_index)

删除指定范围(first_index,last_index)的项目,不指定last_index时,删除一个项目。
删除范围包括两边。

获取项目内容

与删除项函数类似。

listbox对象.get(first_index,last_index)
获取项目个数
listbox对象.size()
获取Listbox内容

需要使用listvariable属性为Listbox对象指定一个对应的变量,例如:

m = StringVar()
listbox = Listbox(tk, listvariable=m)
listbox.insert(0, 'a')
print(m.get())

指定后就可以使用m.get()方法获取Listbox对象中的内容了。
注意:如果允许用户选择多个项目,则需要将Listbox对象的selectmode属性设置为MULTIPLE,表示多选;若设置为SINGLE,则表示单选。

创建从一个列表框选择内容添加到另一个列表框组件的GUI程序。

from tkinter import *
tk = Tk()
tk.title('Listbox')
tk['width'] = 250;tk['height'] = 80
def add():
    for i in listb1.curselection(): # 遍历选中项
        listb2.insert(0,listb1.get(i)) # 添加到右侧列表框

def delete():
    for i in listb2.curselection(): # 遍历选中项
        listb2.delete(i) # 从右侧列表框中删除

lis = ['a','b','c']
listb1 = Listbox(tk)
listb2 = Listbox(tk)
for item in lis: # 给左侧列表框循环插入选项
    listb1.insert(0,item)
listb1.grid(row=0, column=0, rowspan=2)
b1 = Button(tk, text='add', command=add, width=20)
b2 = Button(tk, text='delete', command=delete, width=20)
b1.grid(row=0, column=1)
b2.grid(row=1, column=1)
listb2.grid(row=0, column=2, rowspan=2)
tk.mainloop()

Radiobutton(单选按钮)组件和Checkbutton(复选框)组件

单选按钮和复选框分别用于实现选项的单选和复选功能。Radiobutton组件用于在同一组单选按钮中选择一个单选按钮(不能同时选定多个)。Checkbutton组件用于选择一项或多项。

这连个组件的创建与显示方法与其他组件类似。

可以使用variable属性为Radiobutton组件指定一个对应的变量。如果将多个Radiobutton组件绑定到同一个变量,则这些Radiobutton组件属于同一个分组。分组后需要使用value设置每个Radiobutton组件的值,以标识该项目是否被选中。

Radiobutton组件常用属性
参数描述
variable单选按钮索引变量,通过变量的值确定哪个单选按钮被选中。一组单选按钮使用同一个索引变量。
value单选按钮选中时变量的值。
command单选按钮选中时执行的命令(函数)。
Radiobutton组件的方法
方法名描述
deselect()取消选择。
select()选择。
invoke()调用单选按钮command指定的回调函数。
Checkbutton组件常用属性
参数描述
variable复选框索引变量,通过变量的值确定哪些复选框被选中。每个复选框使用不同的变量,复选框之间相互独立。
onvalue复选框选中(有效)时变量的值。
offvalue复选框未选中(无效)时变量的值。
command复选框选中时执行的命令(函数)。
获取Checkbutton状态

为了弄清楚Checkbutton组件是否被选中,需要使用variable属性为Checkbutton组件指定一个对应变量,例如:

c = IntVar()
c.set(1)
check = Checkbutton(tk, text='a', variable=c, onvalue=1, offvalue=2) # 1为选中,2为没选中
check.pack()
print(c.get())

指定变量c后,可以使用c.get()获取复选框的状态值,也可以使用c.set()设置复选框的状态。例如,设置check复选框对象为未选中状态,代码如下:

c.set(1) # 1为选中,2为没选中

获取单选按钮(Radiobutton)状态的方法类似。

程序示例
from tkinter import *
tk = Tk()
tk.title('Listbox')
tk['width'] = 250;tk['height'] = 80
v = StringVar()
v.set('3') # 设置初始选项值
Radiobutton(tk, variable=v, value='1', text='a').pack()
Radiobutton(tk, variable=v, value='2', text='b').pack()
Radiobutton(tk, variable=v, value='3', text='c').pack()
tk.mainloop()
print(v.get())

Menu(菜单)组件

图形用户界面应用程序通常提供菜单,菜单包含各种按照主题分组的基本命令。图形用户界面应用程序包括如下两种类型的菜单。

主菜单:提供窗体的菜单系统。通过单击可显示下拉子菜单,选择其中的命令可执行相关的操作,常用的主菜单通常包括:文件、编辑、视图、帮助等。

上下文菜单(也称为快捷菜单):通过右击某对象而弹出的菜单,一般为与该对象相关的常用菜单命令,例如,剪切、复制、粘贴等。

例:

from tkinter import *
tk = Tk()
def click():
    print('cilck')
menu = Menu(tk) # 创建菜单对象
for item in ['file', 'edite', 'view']: # 添加菜单标签
    menu.add_command(label=item, command=click) # 给标签添加事件
tk['menu'] = menu # 附加主菜单到窗口
tk.mainloop()

Messagebox(消息窗口)组件

消息窗口(Messagebox)用于弹出提示框进行告警,或选择下一步的操作。消息框包括很多类型,常用的有info、warning、error、yesno、okcancel等,包含不同的图标、按钮以及弹出提示音。

例:

import tkinter as tk
from tkinter import messagebox as msgbox
m = tk.Tk()
m.title("MsgBox")
def b1_click():
    msgbox.showinfo("Info", "Showinfo.")
def b2_click():
    msgbox.showwarning("Warning", "Showwarning.")
def b3_click():
    msgbox.showerror("Error", "Showerror.")
def b4_click():
    msgbox.askquestion("Question", "Askquestion.")
def b5_click():
    msgbox.askokcancel("OkCancel", "Askokcancel.")
def b6_click():
    msgbox.askyesno("YesNo", "Askyesno.")
def b7_click():
    msgbox.askretrycancel("Retry", "Askretrycancel.")
tk.Button(m, text='showinfo', command=b1_click).pack(fill=tk.X)
tk.Button(m, text='showwarning', command=b2_click).pack(fill=tk.X)
tk.Button(m, text='showerror', command=b3_click).pack(fill=tk.X)
tk.Button(m, text='askquestion', command=b4_click).pack(fill=tk.X)
tk.Button(m, text='askokcancel', command=b5_click).pack(fill=tk.X)
tk.Button(m, text='askyesno', command=b6_click).pack(fill=tk.X)
tk.Button(m, text='askretrycancel', command=b7_click).pack(fill=tk.X)
m.mainloop()

Frame(框架)组件

Frame组件是框架组件,负责安排其他组件的位置。Frame组件在屏幕上显示为一个矩形区域,可作为显示其他组件的容器。

创建和显示Frame对象

创建对象

Frame对象=Frame(窗口对象, height=高, width=宽, bg=背景色)

显示对象

Frame对象.pack()
向Frame组件中添加组件

在创建组件时可以指定其容器为Frame组件即可

Label(Frame对象, text='hello').pack()
LabelFrame组件

LabelFrame组件是有标题的Frame组件,可以使用text属性设置LabelFrame组件的标题,方法如下:

LabelFrame(窗口对象, height=高, width=宽, text=标题).pack()
两个Frame组件和一个LabelFrame组件的实例
from tkinter import *

tk = Tk()
tk.title('Frame')
f1 = Frame(tk)
f1.pack()
f2 = Frame(tk)
f2.pack()
lf = LabelFrame(tk,text='label_frame')
lf.pack(side=BOTTOM)
Button(f1, text='f1_button1', fg='red').pack(side=LEFT)
Button(f1, text='f1_button2', fg='brown').pack(side=LEFT)
Button(f1, text='f1_button3', fg='blue').pack(side=LEFT)
Button(f2, text='f2_button', fg='black').pack()
Button(lf, text='lf_button', fg='green').pack()
tk.mainloop()
刷新Frame

用Python制作GUI图形界面,可以使用after()方法每隔几秒刷新GUI图形界面。例如,通过下面代码可实现计数器的功能,并且文字背景色会不断地改变。

from tkinter import *

tk = Tk()
colors = ('red', 'yellow', 'blue', 'green', 'orange')
f = Frame(tk, height=200, width=200)
f.color = 0
f['bg'] = colors[f.color] # 设置框架背景色
lab1 = Label(f, text='0')
lab1.pack()
def foo():
    f.color = (f.color+1) % (len(colors))
    lab1['bg'] = colors[f.color]
    lab1['text'] = str(int(lab1['text'])+1)
    f.after(500, foo) # 每隔500毫秒就执行foo函数刷新屏幕
f.pack()
f.after(500, foo)
tk.mainloop()

我们可以使用after()方法实现移动电子广告效果,只需不断移动lab1即可,代码如下:

from tkinter import *

tk = Tk()
f = Frame(tk, height=200, width=200)
lab1 = Label(f, text='hello world')
x = 0
def foo():
    global x
    x = x+10
    if x>200:
        x = 0
    lab1.place(x=x, y=0)
    f.after(500, foo)
f.pack()
f.after(500, foo)
tk.mainloop()

Tkinter字体

通过组件的font属性,可以设置其显示文本的字体。设置组件字体前首先要能表示一个字体。

通过元组表示字体

通过三个元素的元组,可以表示字体:

(font family, size, modifiers)

素font family是字体名;size为字体大小,单位为point;modifiers为包含粗体、斜体、下画线的样式修饰符。例如:

('Time New Roman', 16, 'bold italic')

例,通过元组表示字体,设置标签label的字体:

from tkinter import *

tk = Tk()
fts = ('Arial', ('Courier New', 19, 'italic'), ('Comic Sans MS',), 'Fixdsys', ('MS Sans Serif',), ('MS Serif',), 'Symbol', 'System', ('Times New Roman',), 'Verdana')
for ft in fts:
    Label(tk, text='hello sticky', font=ft).grid()
tk.mainloop()

字体示例1

通过Font对象表示字体

可以使用tkFont.Font来创建字体。格式如下:

Font(family='字体名', size, weight, slant, underline, overstrike)

其中:size为字体大小;weight=‘bold’或’normal’,'bold’为粗体;slant=‘italic’或’normal’,'italic’为斜体;underline=1或0,1为下画线;overstrike=1或0,1为删除线。

例:

from tkinter import *
from tkinter.font import Font

tk = Tk()
ft = Font(family='Helvetica', size=36, weight='bold')
Label(tk, text='Hello stick', font=ft).grid()
tk.mainloop()

通过tkFont. families()函数可以返回所有可用的字体。

Python事件处理

事件(Event)就是程序中发生的事,例如,用户敲击键盘上的某一个键或单击、移动鼠标。对于这些事件,程序需要做出反应。Tkinter提供的组件通常都有自己可以识别的事件,例如,当按钮被单击时执行特定的操作或当一个输入栏成为焦点,而用户又敲击了键盘上的某些按键,用户所输入的内容就会显示在输入栏内。

程序可以使用事件处理函数来指定当触发某个事件时所做的反应(操作)。

事件类型

事件类型的通用格式:

<[modifier-]...type[-detail]>

事件类型必须放置于尖括号<>内。type描述了类型,例如,键盘按键、鼠标单击。

modifier用于组合键定义,如Control、Alt。detail用于明确定义是哪一个键或按钮的事件,例如,1表示鼠标左键,2表示鼠标中键,3表示鼠标右键。

举例:

<Button-1> # 按下鼠标左键
<KeyPress-A> # 按下A键
<Control-Shift-KyePress-A> # 同时按下Control、Shift、A三键

Python中事件主要有:键盘事件、鼠标事件、窗体事件。

键盘事件

名称描述
KeyPress按下键盘某键时触发,可以在 detail部分指定是哪个键
KeyRelease释放键盘某键时触发,可以在 detail部分指定是啷个键

鼠标事件

名称描述
Button Press或 Button按下鼠标某键,可以在deta部分指定是哪个键
Button Release释放键盘某键时触发,可以在 detail部分指定是啷个键
Motion点中组件的同时拖曳组件移动时触发
Enter当鼠标指针移进某组件时触发
Leave当鼠标指针移出某组件时触发
MouseWheel当鼠标滚轮滚动时触发

窗体事件

名称描述
Visibility当组件变为可视状态时触发
Unmap当组件由显示状态变为隐藏状态时触发
Map当组件由隐藏状态变为显示状态时触发
Expose当组件从原本被其他组件遮盖的状态中暴露出来时触发
FocusIn组件获得焦点时触发
FocusOut组件失去焦点时触发
Configure当改变组件大小时触发,如拖曳窗体边缘
Property当窗体的属性被删除或改变时触发,属于 Tkinter的核心事件
Destroy当组件被销毁时触发
Activate与组件选项中的 state项有关,表示组件由不可用转为可用,如按钮由disabled(灰色)转为 enabled
Deactivate与组件选项中的stae项有关,表示组件由可用转为不可用,如按钮由enabled转为 disabled(灰色)

modifier组合键定义中常用的修饰符

修饰符描述
Alt当按下【A】键
Any按下任何键,如
Control按下【ct】键
Double两个事件在短时间内发生,如双击鼠标左键< Double- Button-1>
Lock当按下【 Caps Lock】键
Shift当按下【Shif】键
Triple类似于 Double,三个事件在短时间内发生

可以短格式表示事件,例如:<1>等同于,等同于。

对于大多数的单字符按键,用户还可以忽略“<>”符号。但是空格键和尖括号键不能忽略(正确的表示方式分别为、)。

事件绑定

程序建立一个处理某一事件的事件处理函数,称之为绑定。

  1. 创建组件对象时绑定

    创建组件对象实例时,可通过其命名参数command绑定事件处理函数。例如:

    def callback():
    	showinfo("hello")
    Button(tk, text="hello", command=callback).pack()
    
  2. 实例绑定

    调用组件对象实例方法bind()可为指定组件实例绑定事件,这是最常用的事件绑定方式。

    组件对象实例名.bind("<事件类型>",  事件处理函数)
    

    假设声明了一个名为canvas的Canvas组件对象,若要在canvas上按下鼠标左键时绘制一条线,可以这样实现:

    canvas.bind('<Button-1>', drawline)
    

    其中,bind()函数的第一个参数是事件描述符,指定无论什么时候在canvas上,当按下鼠标左键时就调用事件处理函数drawline进行绘制线条的任务。特别需要注意的是:drawline后面的圆括号是省略的,Tkinter会将此函数填入相关参数后调用运行,在这里只是声明而已。

  3. 标识绑定

    在Canvas画布中绘制各种图形,将图形与事件绑定可以使用标识绑定tag_bind()函数。预先为图形定义标识tag后,再通过标识tag来绑定事件。例如:

    cv.tag_bind('r1', '<Button-1>', printRect)
    

    示例:

    from tkinter import *
    
    tk = Tk()
    def printRect1(event):
    	print('rectangle左键事件')
    def printRect2(event):
    	print('rectangle右键事件')
    def printLine(event):
    	print('Line事件')
    cv = Canvas(tk, bg='white') # 创建一个Canvas,设置其背景为白色
    rt1 = cv.create_rectangle(10, 10, 110, 110, width=8, tags='r1')
    cv.tag_bind('r1', '<Button-1>', printRect1) # 绑定item与鼠标左键事件
    cv.tag_bind('r1', '<Button-3>', printRect2) # 绑定item与鼠标右键事件
    # 创建一个line,并将其tags设置为'r2'
    cv.create_line(180, 70, 280, 70, width=10, tags='r2')
    cv.tag_bind('r2', '<Button-1>', printLine) # 绑定item与鼠标左键事件
    cv.pack()
    tk.mainloop()
    

    这个示例中,单击矩形的边框时才会触发事件,矩形既响应鼠标左键又响应右键。使用鼠标左键单击矩形边框时出现“rectangle左键事件”信息,使用鼠标右键单击矩形边框时出现“rectangle右键事件”信息,使用鼠标左键单击直线时则出现“Line事件”信息。

事件处理函数
  1. 定义事件处理函数

    事件处理函数往往带有一个event参数。触发事件调用事件处理函数时,将传递Event对象实例。

    def callback(event): # 事件处理函数
    	showinfo("info")
    
  2. Event事件处理参数属性

    可以获取Event对象实例的各种相关参数,Event事件对象的主要参数属性如下

    参数说明
    .x,.y鼠标相对于组件对象左上角的坐标
    .x_roo,.y_roo鼠标相对于屏幕左上角的坐标
    .keysym字符串命名按键,例如: Escape、F1~F12、 Scroll lock、 Pause、 Insert、Delete、Home、 Prior(这个是 Page Up)、Next(这个是 Page Down)End、Up、 Right、Left、Down、 Shit L、 Shift R、 Contro_L、 Control_R、AltR、WinL
    .keysym_num数字代码命名按键
    .keycode键码,但是它不能反映事件前缀:At、 Contro、Shit、Lock,并且它不区分大小写按键,即输入a和A是相同的键码
    .time时间
    .type事件类型
    .widget触发事件的对应组件
    .char字符

    Event事件对象按键的详细信息说明如下

    .keysym.keycode.keysym_num说明
    Alt_L6465513左边的【At】键
    AIt_R11365514右边的【At】键
    BackSpace2265288【 BackSpace】键
    Cancel11065387【 Pause Break】键
    F1~F1167~7765470~65480功能键【F1】~【F11】
    Print11165377打印屏幕键
触发KeyPress键盘事件的例子
from tkinter import *

tk = Tk()
def printkey(event):
    print('按下了:'+event.char)
entry = Entry(tk)
entry.bind('<KeyPress>', printkey) # 绑定按键监听事件<KeyPress>,监听任何按键
entry.pack()
tk.mainloop()
获取鼠标单击标签Label时坐标的鼠标事件示例
from tkinter import *

tk = Tk()
def leftClick(event):
    print('(x,y):',event.x,event.y)
    print('相对于屏幕左上角x轴,y轴:',event.x_root,event.y_root)
lab = Label(tk, text='x,y')
lab.pack()
lab.bind('<Button-1>', leftClick)
tk.mainloop()
  • 4
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值