Python功能包之Tkinter——窗口视图GUI

窗口

窗口与分辨率

import tkinter as tk

window = tk.Tk()# 创建一个Tk对象,这是创建GUI的主窗口
window.title('my window') # 设置主窗口的标题为'my window'
# window.geometry('200x100+200+200') # 设置主窗口的大小为宽200x高100,并设置打开位置
a = window.maxsize() # 获取分辨率
# print(a)
k,g=a
window.geometry(f'{k//2}x{g//2}') # 设置主窗口的大小为获取分辨率的一半,并设置打开位置
window.mainloop()

输出:
(1536, 864)
他的大小为一半
在这里插入图片描述

窗口缩放与图标

import tkinter as tk
a1 = tk.Tk()
a1.title('111')
a1.geometry('500x500+100+100')

# 设置窗口锁定缩放(False就是锁定)
a1.resizable(width=False, height=False)
# 设置窗口图标(ico格式的)
a1.iconbitmap("C:\\Users\HP\Pictures\\10.ico")

a1.mainloop()

输出:
在这里插入图片描述

窗口背景与透明度

import tkinter as tk
a1 = tk.Tk()
a1.title('111')
a1.geometry('500x500')
# 设置窗口背景颜色(颜色编码值或者写英文)
a1.configure(bg='#990066')
# 设置窗口透明度(0-1的透明度设置)
a1.attributes('-alpha', 0.5)
a1.mainloop()

输出:
在这里插入图片描述

窗口置顶与销毁

import tkinter as tk
a1 = tk.Tk()
a1.title('111')
a1.geometry('500x500')
# 设置窗口置顶
a1.attributes('-topmost', True)

def guan():
    # 这里可以设置弹窗确认是否确认关闭的操作
    print('1111')
    # 销毁窗口
    a1.destroy()
# 设置窗口关闭时执行函数
a1.protocol('WM_DELETE_WINDOW', guan)
a1.mainloop()

组件

标签与按钮

Label与Button

import tkinter as tk

window = tk.Tk()# 创建一个Tk对象,这是创建GUI的主窗口
window.title('my window') # 设置主窗口的标题为'my window'
window.geometry('200x100') # 设置主窗口的大小为宽200x高100

var = tk.StringVar() # 创建一个StringVar对象,用于存储和操作字符串
l = tk.Label(window, textvariable=var, bg='green', font=('Arial', 12), width=15, height=2)
'''
创建一个Label(标签)对象
window:标签所属的父窗口
textvariable=var:标签的文本内容由var变量决定
text='':直接设置里面内容,而不是用bar变量决定
fg='rea':设置文本颜色为红色
bg='green':标签的背景颜色为绿色
font=('Arial', 12):标签的字体为Arial,大小为12
width=15:标签的宽度为15个字符
height=2:标签的高度为2行
'''

l.pack() # 将标签放置到主窗口中
on_hit = False # 初始化一个布尔变量on_hit为False,为后面按钮用的

def hit_me():
    global on_hit # 声明on_hit为全局变量
    if on_hit == False:
        on_hit = True
        var.set('you hit me')
    else:
        on_hit = False
        var.set('')
# 当on_hit为False时,将on_hit设为True,并将标签的文本设置为'you hit me'
# 当on_hit为True时,将on_hit设为False,并将标签的文本设置为空字符串

b = tk.Button(window, text='hit me', width=15, height=2, command=hit_me)
'''创建一个Button(按钮)对象
window:按钮所属的父窗口
text='hit me':按钮上的文本为'hit me'
width=15:按钮的宽度为15个字符
height=2:按钮的高度为2行
command=hit_me:按钮被点击时调用hit_me函数'''

b.pack() # 将按钮放置到主窗口中
window.mainloop() # 进入主事件循环,使窗口保持显示状态并处理用户交互

输出:
当没点击时
在这里插入图片描述
点击后
在这里插入图片描述

输入与文本框

Entry与Text

import tkinter as tk

window = tk.Tk()
window.title('my window')
window.geometry('200x200')

e = tk.Entry(window, show='*')
# 创建一个Entry(输入框)对象,用于用户输入
# show='*'表示输入的字符会以星号显示,通常用于密码输入(可以设置为None就可以看对应的输入了)
e.pack()

def insert_point():
    var = e.get()
    t.insert('insert', var)
# 函数的功能是获取输入框e中的文本,并将其插入到文本框t的当前光标位置

def insert_end():
    var = e.get()
    t.insert('end', var)
# 函数的功能是获取输入框e中的文本,并将其插入到文本框t的末尾,‘end’可以改为其他的,比如1.1就是一行一位;2.1就是第二行第二位

b1 = tk.Button(window, text='insert point', width=15, height=2, command=insert_point)
'''创建一个Button(按钮)对象b1
按钮上的文本为'insert point',宽度为15,高度为2
当按钮被点击时,调用insert_point函数'''
b1.pack()

b2 = tk.Button(window, text='insert end', width=15, height=2, command=insert_end)
b2.pack()

t = tk.Text(window, height=2) # 创建一个Text(文本框)对象t,高度为2行
t.pack() # 将文本框t添加到主窗口中
window.mainloop()

输出:
在这里插入图片描述
光标在第二位,但点击insert end会自动加到最后
在这里插入图片描述

列表部件

Listbox

import tkinter as tk

# 创建主窗口
window = tk.Tk()
window.title('my window')  # 设置窗口标题
window.geometry('200x200')  # 设置窗口大小

# 创建一个字符串变量
var1 = tk.StringVar()
# 创建一个标签,背景色为黄色,宽度为4,文本内容绑定到var1变量
l = tk.Label(window, bg='yellow', width=4, textvariable=var1)
l.pack()

def print_selection():
    # 获取列表框中当前选中项的值
    value = lb.get(lb.curselection())
    # 将获取到的值设置到var1变量中,这样会更新标签的显示内容
    var1.set(value)

# 创建一个按钮,文本为'print selection',宽度为15,高度为2,点击时执行print_selection函数
b1 = tk.Button(window, text='print_selection', width=15, height=2, command=print_selection)
b1.pack()

# 创建一个字符串变量,并设置其初始值为(11, 22, 33, 44)
var2 = tk.StringVar()
var2.set((11, 22, 33, 44))
# 创建一个列表框,其内容由var2变量决定
lb = tk.Listbox(window, listvariable=var2)
lb.insert(1, 'first') # 在列表框的索引为1的位置插入'first'
lb.insert(2, 'second')
lb.delete(2) # 删除列表框中索引为2的元素
lb.pack()

window.mainloop()

输出:
在这里插入图片描述

下拉列表(组合框)

import tkinter as tk
from tkinter.ttk import *

root = tk.Tk()
root.title("Text")
root.geometry("500x500")

# 创建一个整型变量,用于存储Combobox的选择值
sexVar = tk.IntVar()
# 创建一个Combobox(下拉列表框),并将其与sexVar变量绑定
cmb_ip_list = tk.ttk.Combobox(root, textvariable=sexVar)
# 定义一个列表,包含"男"和"女"两个选项
sex_list = ["男", "女"]
# 设置Combobox的选项值为sex_list中的内容
cmb_ip_list["value"] = sex_list
# 设置Combobox的默认选中项为列表中的第二项(索引为1,即"女")
cmb_ip_list.current(1)
cmb_ip_list.pack()

root.mainloop()

输出:
在这里插入图片描述

选择按钮

Radiobutton

import tkinter as tk

window = tk.Tk()
window.title('my window')
window.geometry('500x500')

var = tk.StringVar()
l = tk.Label(window, bg='yellow', width=40,text='')
l.pack()
def print_selection():
    l.config(text='you have selected ' + var.get())

# 创建第一个单选按钮(Radiobutton)对象
# 文本为'Option A',关联变量为var,选项值为'A',选择时调用print_selection函数
r1 = tk.Radiobutton(window, text='Option A', variable=var, value='A', command=print_selection)
# 将第一个单选按钮放置到窗口中
r1.pack()
r2 = tk.Radiobutton(window, text='Option B', variable=var, value='B', command=print_selection)
r2.pack()
r3 = tk.Radiobutton(window, text='Option C', variable=var, value='C', command=print_selection)
r3.pack()

window.mainloop()

输出:
在这里插入图片描述

尺度

Scale

import tkinter as tk

# 创建主窗口
window = tk.Tk()
window.title('my window')  # 设置窗口标题
window.geometry('300x300')  # 设置窗口大小

l = tk.Label(window, bg='yellow', width=20, text='')
l.pack()

# 定义一个函数,用于处理Scale滑块的事件
def print_selection(v):
    # 更新标签的文本内容,显示滑块当前的值
    l.config(text='you have selected ' + v)

# 创建一个Scale滑块
s = tk.Scale(window,
             label='try me',  # 设置滑块的标签为'try me'
             from_=0, to=12,  # 设置滑块的取值范围从0到12
             orient=tk.HORIZONTAL,  # 设置滑块为水平方向
             length=200,  # 设置滑块的长度为200像素
             showvalue=0,  # 不显示滑块当前的值
             tickinterval=3,  # 设置刻度间隔为3
             resolution=0.01,  # 设置滑块的精度为0.01
             command=print_selection)  # 当滑块值改变时,调用print_selection函数
s.pack()

window.mainloop()

输出:
在这里插入图片描述

勾选项

Checkbutton

import tkinter as tk

# 创建主窗口
window = tk.Tk()
window.title('my window')  # 设置窗口标题
window.geometry('300x300')  # 设置窗口大小

l = tk.Label(window, bg='yellow', width=20, text='')
l.pack()

def print_selection():
    # 根据两个复选框的选择状态,更新标签的文本内容
    if (var1.get() == 1) and (var2.get() == 0):
        l.config(text='I love only Python ')
    elif (var1.get() == 0) and (var2.get() == 1):
        l.config(text='I love only C++')
    elif (var1.get() == 0) and (var2.get() == 0):
        l.config(text='I do not love either')
    else:
        l.config(text='I love both')

# 创建两个整型变量,用于存储复选框的状态
var1 = tk.IntVar()
var2 = tk.IntVar()
# 文本为'Python',关联变量为var1,选中时值为1,未选中时值为0,点击时调用print_selection函数
c1 = tk.Checkbutton(window, text='Python', variable=var1, onvalue=1, offvalue=0, command=print_selection)
c2 = tk.Checkbutton(window, text='C++', variable=var2, onvalue=1, offvalue=0, command=print_selection)
c1.pack()
c2.pack()

window.mainloop()

输出:
在这里插入图片描述
在这里插入图片描述

画布

Canvas

import tkinter as tk

# 创建主窗口
window = tk.Tk()
window.title('my window')  # 设置窗口标题
window.geometry('400x400')  # 设置窗口大小

# 创建一个画布(Canvas),背景颜色为蓝色,高度为300像素,宽度为200像素
canvas = tk.Canvas(window, bg='blue', height=300, width=200)
image_file = tk.PhotoImage(file='D:\pythonProject\image/9.jpg')
# 在画布上创建图像,位置为(10, 10),锚点为左上角(northwest),使用加载的图片
image = canvas.create_image(10, 10, anchor='nw', image=image_file)
x0, y0, x1, y1 = 50, 50, 80, 80
line = canvas.create_line(x0, y0, x1, y1) # 在画布上创建一条线,起点为(x0, y0),终点为(x1, y1)
oval = canvas.create_oval(x0, y0, x1, y1, fill='red') # 在画布上创建一个填充为红色的椭圆,使用定义的坐标点作为外接矩形
arc = canvas.create_arc(x0+30,y0+30,x1+30,y1+30,start=0, extent=180) # 在画布上创建一个弧形,起始角度为0度,扩展角度为180度,位置基于之前的坐标点偏移
rect= canvas.create_rectangle(100,30,100+20,30+20) # 在画布上创建一个矩形,位置为(100, 30),大小为20x20
canvas.pack()

def moveit():
    # 在画布上移动矩形,水平移动0像素,垂直移动2像素
    canvas.move(rect,0,2)
    
# 创建一个按钮,文本为'move',点击时调用moveit函数,并将按钮放置到窗口中
b = tk.Button(window, text='move', command=moveit).pack()

window.mainloop()

输出:
在这里插入图片描述
若点击几次移动
在这里插入图片描述

菜单

Menubar

import tkinter as tk

window = tk.Tk()
window.title('my window')
window.geometry('200x200')

l = tk.Label(window, text="", bg='yellow')
l.pack()

# 初始化一个计数器变量
counter = 0

# 定义一个函数,用于更新标签的文本内容并增加计数器的值
def do_job():
    global counter
    # 更新标签的文本内容,显示'do'加上当前的计数器值
    l.config(text='do ' + str(counter))
    counter += 1

# 创建菜单栏
menubar = tk.Menu(window)

# 创建文件菜单
filemenu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label='File', menu=filemenu) # 将文件菜单添加到菜单栏中,标签为'File'

filemenu.add_command(label='New', command=do_job) # 向文件菜单中添加'New'命令,点击时调用do_job函数
filemenu.add_command(label='Open', command=do_job)
filemenu.add_command(label='Save', command=do_job)
# 在文件菜单中添加一条分隔线
filemenu.add_separator()
filemenu.add_command(label='Exit', command=window.quit) # 向文件菜单中添加'Exit'命令,点击时关闭窗口

# 创建编辑菜单
editmenu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label='Edit', menu=editmenu) # 将编辑菜单添加到菜单栏中,标签为'Edit'
editmenu.add_command(label='Cut', command=do_job)
editmenu.add_command(label='Copy', command=do_job)
editmenu.add_command(label='Paste', command=do_job)

# 创建子菜单
submenu = tk.Menu(filemenu)
filemenu.add_cascade(label='Import', menu=submenu, underline=0) # 将子菜单添加到文件菜单中,标签为'Import'
submenu.add_command(label="Submenu1", command=do_job) # 向子菜单中添加'Submenu1'命令,点击时调用do_job函数
window.config(menu=menubar) # 将菜单栏配置到窗口中
window.mainloop()

输出:
在这里插入图片描述

框架

Frame

import tkinter as tk

window = tk.Tk()
window.title('my window')
window.geometry('200x200')
tk.Label(window, text='on the window').pack()

# 创建一个框架(Frame),它属于window,并将其放置在窗口中
frm = tk.Frame(window)
frm.pack()

# 创建两个子框架,它们都属于frm
frm_l = tk.Frame(frm)
frm_r = tk.Frame(frm)

# 将frm_l框架放置在frm的左侧
frm_l.pack(side='left')
# 将frm_r框架放置在frm的右侧
frm_r.pack(side='right')

# 在frm_l框架中创建一个标签,显示文本'on the frm_l1',并将其放置在frm_l中
tk.Label(frm_l, text='on the frm_l1').pack()
tk.Label(frm_l, text='on the frm_l2').pack()
# 在frm_r框架中创建一个标签,显示文本'on the frm_r1',并将其放置在frm_r中
tk.Label(frm_r, text='on the frm_r1').pack()
window.mainloop()

输出:
在这里插入图片描述

弹窗

messagebox


import tkinter as tk
from tkinter import messagebox

window = tk.Tk()
window.title('my window')
window.geometry('200x200')

def hit_me():
    # tk.messagebox.showinfo(title='Hi', message='hahaha')
    # 这行代码如果取消注释,会弹出一个信息提示框,标题为'Hi',内容为'hahaha'

    # tk.messagebox.showwarning(title='Hi', message='nonono')
    # 这行代码如果取消注释,会弹出一个警告提示框,标题为'Hi',内容为'nonono'

    # tk.messagebox.showerror(title='Hi', message='No!! never')
    # 这行代码如果取消注释,会弹出一个错误提示框,标题为'Hi',内容为'No!! never'

    # print(tk.messagebox.askquestion(title='Hi', message='hahaha'))
    # 这行代码如果取消注释,会弹出一个询问框,标题为'Hi',内容为'hahaha',并且会在控制台打印出'yes'或'no'

    print(tk.messagebox.askyesno(title='Hi', message='hahaha'))
    # 这行代码会弹出一个询问是否的对话框,标题为'Hi',内容为'hahaha',并且会在控制台打印出True或False

tk.Button(window, text='hit me', command=hit_me).pack()
window.mainloop()

输出:
在这里插入图片描述

顶层窗口

那么除了弹窗会弹出新窗口外,我们自己也可以写窗口里创建新的窗口,利用的方法是tk.Toplevel()方法,具体如何运用请见:
示例里的登录窗口中:点击注册按钮的弹窗

放置位置

pack grid place

# 法一
import tkinter as tk

window = tk.Tk()
window.title('my window')
window.geometry('200x200')
tk.Label(window, text='1').pack(side='top')
tk.Label(window, text='1').pack(side='bottom')
tk.Label(window, text='1').pack(side='left')
tk.Label(window, text='1').pack(side='right')

window.mainloop()

输出:
在这里插入图片描述

import tkinter as tk

window = tk.Tk()
window.title('my window')
window.geometry('200x200')
for i in range(4):
    for j in range(3):
        tk.Label(window, text=1).grid(row=i, column=j, ipadx=10, ipady=10)
        # 创建了一个 3x3 的网格,每个标签内部有 10 像素的水平和垂直填充。

window.mainloop()

输出:
在这里插入图片描述

import tkinter as tk

window = tk.Tk()
window.title('my window')
window.geometry('200x200')
tk.Label(window, text=1).place(x=10,y=100, anchor='nw')
# x=10表示标签的x坐标为10,y=100表示标签的y坐标为100
# anchor='nw'表示标签的左上角(northwest)作为锚点,用于定位

window.mainloop()

输出:
在这里插入图片描述

示例

登录窗口

import tkinter as tk
from PIL import Image, ImageTk
import pickle
from tkinter import messagebox

window = tk.Tk()
window.title('Welcome to my Python')
window.geometry('450x300')

# welcome image
canvas = tk.Canvas(window, height=200, width=300)
# 使用Pillow库加载图像
image_file = Image.open(r"D:\pythonProject\image\welcome.png")
image_file = ImageTk.PhotoImage(image_file)
image = canvas.create_image(0, 0, anchor='nw', image=image_file)
# 在画布的左上角(northwest)创建一个图像,使用之前加载的图像文件
canvas.pack(side='top')

# user information
tk.Label(window, text='User name: ').place(x=50, y=150)
# 在窗口中创建一个标签,显示文本'User name: ',并将其放置在坐标(50, 150)处
tk.Label(window, text='Password: ').place(x=50, y=190)

var_usr_name = tk.StringVar() # 用于存储用户名
var_usr_name.set('example@python.com') # 设置字符串变量的初始值为'example@python.com'
entry_usr_name = tk.Entry(window, textvariable=var_usr_name)
# 创建一个输入框(Entry),属于window窗口,并且将其文本变量设置为之前创建的var_usr_name
entry_usr_name.place(x=160, y=150)
var_usr_pwd = tk.StringVar() # 创建一个字符串变量,用于存储用户密码
entry_usr_pwd = tk.Entry(window, textvariable=var_usr_pwd, show='*')
# 创建一个输入框(Entry),属于window窗口,并且将其文本变量设置为之前创建的var_usr_pwd,show='*'表示输入的字符将以星号显示,用于密码输入框
entry_usr_pwd.place(x=160, y=190)

# 定义用户登录函数
def usr_login():
    # 获取用户输入的用户名和密码
    usr_name = var_usr_name.get()
    usr_pwd = var_usr_pwd.get()

    try:
        # 尝试以二进制读取模式打开用户信息文件
        with open('usrs_info.pickle', 'rb') as usr_file:
            usrs_info = pickle.load(usr_file)
    except FileNotFoundError:
        # 如果文件不存在,则创建一个默认的用户信息文件
        with open('usrs_info.pickle', 'wb') as usr_file:
            usrs_info = {'admin': 'admin'}
            pickle.dump(usrs_info, usr_file)

    # 检查用户名是否存在于用户信息中
    if usr_name in usrs_info:
        # 如果用户名存在,检查密码是否正确
        if usr_pwd == usrs_info[usr_name]:
            # 如果密码正确,显示欢迎信息
            tk.messagebox.showinfo('Welcome', 'How are you? ' + usr_name)
        else:
            # 如果密码错误,显示错误信息
            tk.messagebox.showerror('Error', 'Your password is wrong, try again.')
    else:
        # 如果用户名不存在,询问用户是否要注册
        is_sign_up = tk.messagebox.askyesno('Welcome', 'You have not sign up yet. Sign up?')
        if is_sign_up:
            # 如果用户选择注册,调用注册函数
            usr_sign_up()


# 定义用户注册函数
def usr_sign_up():
    # 定义内部函数,用于处理注册逻辑
    def sign_to_Mofan_Python():
        # 获取用户输入的新密码、确认密码和新用户名
        np = new_pwd.get()
        npf = new_pwd_confirm.get()
        nn = new_name.get()

        with open('usrs_info.pickle', 'rb') as usr_file:
            exist_usr_info = pickle.load(usr_file)

        # 检查新密码和确认密码是否一致
        if np!= npf:
            # 如果不一致,显示错误信息
            tk.messagebox.showerror('Error', 'Password and confirm password must be the same!')
        elif nn in exist_usr_info:
            # 如果用户名已存在,显示错误信息
            tk.messagebox.showerror('Error', 'The user has already existed!')
        else:
            # 如果所有条件都满足,将新用户信息添加到用户信息文件中
            exist_usr_info[nn] = np
            with open('usrs_info.pickle', 'wb') as usr_file:
                pickle.dump(exist_usr_info, usr_file)
            # 显示注册成功信息,并关闭注册窗口
            tk.messagebox.showinfo('Welcome', 'You have successfully signed up!')
            window_sign_up.destroy()

    # 创建一个新的注册窗口
    window_sign_up = tk.Toplevel(window)
    window_sign_up.geometry('350x200')
    window_sign_up.title('Sign up window')

    # 创建用于存储新用户名的变量,并设置默认值
    new_name = tk.StringVar()
    new_name.set('example@python.com')
    tk.Label(window_sign_up, text='User name: ').place(x=10, y=10)
    entry_new_name = tk.Entry(window_sign_up, textvariable=new_name)
    entry_new_name.place(x=150, y=10)

    # 创建用于存储新密码的变量
    new_pwd = tk.StringVar()
    tk.Label(window_sign_up, text='Password: ').place(x=10, y=50)
    entry_usr_pwd = tk.Entry(window_sign_up, textvariable=new_pwd, show='*')
    entry_usr_pwd.place(x=150, y=50)

    # 创建用于存储确认密码的变量
    new_pwd_confirm = tk.StringVar()
    tk.Label(window_sign_up, text='Confirm password: ').place(x=10, y=90)
    entry_usr_pwd_confirm = tk.Entry(window_sign_up, textvariable=new_pwd_confirm, show='*')
    entry_usr_pwd_confirm.place(x=150, y=90)

    # 创建注册按钮,点击时调用注册逻辑函数
    btn_comfirm_sign_up = tk.Button(window_sign_up, text='Sign up', command=sign_to_Mofan_Python)
    btn_comfirm_sign_up.place(x=150, y=130)


# 创建登录按钮,点击时调用登录函数
btn_login = tk.Button(window, text='Login', command=usr_login)
btn_login.place(x=170, y=230)
# 创建注册按钮,点击时调用注册函数
btn_sign_up = tk.Button(window, text='Sign up', command=usr_sign_up)
btn_sign_up.place(x=270, y=230)

# 进入主事件循环,保持窗口显示
window.mainloop()

输出:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

补充知识

pickle是 Python 中的一个标准库,用于实现数据的序列化和反序列化操作。

  1. 序列化(Pickling)
    序列化是将对象转换为字节流的过程,这样可以将对象保存到文件中、存储在数据库中或者通过网络传输。
import pickle

data = {'name': 'John', 'age': 30, 'city': 'New York'}
with open('data.pickle', 'wb') as file:
    pickle.dump(data, file)

上述代码中,pickle.dump()函数用于将data字典对象序列化并保存到data.pickle文件中。这里使用wb模式,表示以二进制写入模式打开文件。

  1. 反序列化(Unpickling)
    反序列化是将字节流转换回对象的过程,这样可以从文件、数据库或者网络中获取数据并恢复为原始的对象。
import pickle

with open('data.pickle', 'rb') as file:
    loaded_data = pickle.load(file)
print(loaded_data)

上述代码中,pickle.load()函数用于从data.pickle文件中读取字节流并反序列化恢复为原始的对象。这里使用rb模式,表示以二进制读取模式打开文件。

设置顶层窗口聚焦:
window.focus_set() # 利用该函数,在跳转的窗口会自动聚焦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啥都鼓捣的小yao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值