用Tkinter打造GUI开发工具(28)可视化设计之Grid布局及生成代码

用Tkinter打造GUI开发工具(28)可视化设计之Grid布局及生成代码

Python Tkinter库是Python开发团队首推的GUI库,Python自带编辑器IDLE就是建立在Tkinter基础上的,因此成为 Python 3.6版本以上的标准内置库。
很多说Tkinter不好用的朋友有两个问题,一是不了解Tkinter的优美,我在任何场合都说Tkinter相当于C语言,Pyqt相当于C++。 但是Tkinter也支持C++的语法,也就是说Tkinter除了支持C语言的函数式语法外,还支持C++语言的面对对象语法。因此HP_tk、HP_tk2以及easygui,turtle,…很多国外软件都是用Tkinter开发Python应用软件。
我这里用Tkinter开发一个Tkinter的可视化开发工具,这个工具建立在我开发的HP_tk2扩展库的基础上,显而易见,这都是Tkinter库的再次封装而已。即便我不写,也会有其他编成高手能够实现。这说明了什么,说明Tkinter无比强大,你如果掌握编程技巧和算法,你可以用Tkinter 开发类似Pyqt库,或者开发类似Visual Studio Code,PyCharm等软件。
Tkinter GUI库为我们提供了Pack、Grid、Place、Form四种布局,上一篇我们介绍了Place布局的可视化开发技术,这篇介绍Grid布局的可视化开发设计。
一般应用软件都是方块结构,因此使用Grid布局能够快速把稿纸变为代码。但是对于不熟悉Grid布局的编程着,自然感觉不如其他可视化开发工具,能够利用所见所得的可视化设计工具,根据用户设计的结果,生成布局代码。Tkinter原生库没有可视化,我们自己封装了一个可视化开发类,基于Frame类在Tkinter中就算一个控件或组件。
我们仍然要依赖HP_tk2来实现设个设计程序。

# Tkinter GUI可视化生成代码验证程序--Grid布局
import tkinter as tk
import tkinter as ttk
import tkinter.tix as tix 
from tkinter.constants import *
import random
import HP_tk2 as htk


if __name__ == '__main__':
    root = tix.Tk()   #主窗口root
    root.title("可视化设计GRId")
   
    f0=tk.Toplevel(root)  #可视化子窗
    f0.title('GRId布局设计')  #Tkinter中设置窗口标题方法
    top=htk.resizewidget(f0,800,600)  #建立可调部件区域
    f1=tk.Frame(top)
    f1.place(x=0, y=0,  #坐标起点(0,0)
                    width=500, #部件相对于窗口的宽度
                    height=400, #部件相对于窗口的高度
                    bordermode=tk.OUTSIDE  #部件边框模式
                    )  #使用place方法的相对位置
    top.setwidget(f1)  #加入可调部件

    grd=htk.gridwidget(f1,row=8,column=9)

    def btn_cmd2():
        d=grd.to_dict()
        print(d)
        print(len(d))

    def btn_cmd3():
        d={0: (0, 0, 3, 3, 0), 1: (1, 0, 1, 1, 0), 2: (2, 0, 1, 1, 0), 3: (3, 0, 1, 1, 3), 4: (4, 0, 1, 1, 4), 5: (5, 0, 1, 1, 5), 6: (6, 0, 1, 1, 6), 7: (7, 0, 1, 1, 7), 8: (8, 0, 1, 1, 8), 9: (0, 1, 1, 1, 0), 10: (1, 1, 1, 1, 0), 11: (2, 1, 1, 1, 0), 12: (3, 1, 1, 1, 12), 13: (4, 1, 1, 1, 13), 14: (5, 1, 1, 1, 14), 15: (6, 1, 1, 1, 15), 16: (7, 1, 1, 1, 16), 17: (8, 1, 1, 1, 17), 18: (0, 2, 1, 1, 0), 19: (1, 2, 1, 1, 0), 20: (2, 2, 1, 1, 0), 21: (3, 2, 1, 1, 21), 22: (4, 2, 1, 1, 22), 23: (5, 2, 1, 1, 23), 24: (6, 2, 1, 1, 24), 25: (7, 2, 1, 1, 25), 26: (8, 2, 1, 1, 26), 27: (0, 3, 1, 1, 27), 28: (1, 3, 1, 1, 28), 29: (2, 3, 1, 1, 29), 30: (3, 3, 1, 1, 30), 31: (4, 3, 1, 1, 31), 32: (5, 3, 1, 1, 32), 33: (6, 3, 1, 1, 33), 34: (7, 3, 1, 1, 34), 35: (8, 3, 1, 1, 35), 36: (0, 4, 1, 1, 36), 37: (1, 4, 1, 1, 37), 38: (2, 4, 1, 1, 38), 39: (3, 4, 1, 1, 39), 40: (4, 4, 1, 1, 40), 41: (5, 4, 1, 1, 41), 42: (6, 4, 1, 1, 42), 43: (7, 4, 1, 1, 43), 44: (8, 4, 1, 1, 44), 45: (0, 5, 1, 1, 45), 46: (1, 5, 1, 1, 46), 47: (2, 5, 1, 1, 47), 48: (3, 5, 1, 1, 48), 49: (4, 5, 1, 1, 49), 50: (5, 5, 1, 1, 50), 51: (6, 5, 1, 1, 51), 52: (7, 5, 1, 1, 52), 53: (8, 5, 1, 1, 53), 54: (0, 6, 1, 1, 54), 55: (1, 6, 1, 1, 55), 56: (2, 6, 1, 1, 56), 57: (3, 6, 1, 1, 57), 58: (4, 6, 1, 1, 58), 59: (5, 6, 1, 1, 59), 60: (6, 6, 1, 1, 60), 61: (7, 6, 1, 1, 61), 62: (8, 6, 1, 1, 62), 63: (0, 7, 1, 1, 63), 64: (1, 7, 1, 1, 64), 65: (2, 7, 1, 1, 65), 66: (3, 7, 1, 1, 66), 67: (4, 7, 1, 1, 67), 68: (5, 7, 1, 1, 68), 69: (6, 7, 1, 1, 69), 70: (7, 7, 1, 1, 70), 71: (8, 7, 1, 1, 71)}
        grd.clear()
        grd.read_dict(d)

    def btn_cmd4():
        py=grd.to_py() 
        print(py)

      
    btn=tk.Button(root,text='生成代码',command=btn_cmd2)
    btn.place(x=10,y=10)

    btn3=tk.Button(root,text='装载数据',command=btn_cmd3)
    btn3.place(x=10,y=50)

    btn4=tk.Button(root,text='生成代码',command=btn_cmd4)
    btn4.place(x=10,y=100)    

    root.mainloop()

这个程序创建了一个row=8,column=9的Grid布局,经过设计,可以生成一个布局py程序。
在这里插入图片描述
在不同的区域,鼠标右键弹出菜单来进行合并或拆分单元。
在这里插入图片描述
下图是我们设计的一个布局图。
在这里插入图片描述
点按钮[生成代码],生成如下布局图。

import tkinter as tk
import tkinter as ttk
import tkinter.tix as tix 
from tkinter.constants import *

root = tix.Tk()   #主窗口root
root.title("可视化设计结果")
f1=tk.Frame(root)
f1.place(x=0, y=0,  #坐标起点(0,0)
                    width=500, #部件相对于窗口的宽度
                    height=400, #部件相对于窗口的高度
                    bordermode=tk.OUTSIDE  #部件边框模式
                    )  #使用place方法的相对位置


button0 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid0')
button0.grid(row=0, column=0, padx=1, pady=1,rowspan=3,columnspan=3)

f1.columnconfigure(0,weight=1)
f1.rowconfigure(0,weight=1)
                    
f1.columnconfigure(1,weight=1)
f1.rowconfigure(1,weight=1)
                    
f1.columnconfigure(2,weight=1)
f1.rowconfigure(2,weight=1)
                    
button3 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid3')
button3.grid(row=0, column=3, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(3,weight=1)
f1.rowconfigure(3,weight=1)
                    
button4 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid4')
button4.grid(row=0, column=4, padx=1, pady=1,rowspan=1,columnspan=4)

f1.columnconfigure(4,weight=1)
f1.rowconfigure(4,weight=1)
                    
f1.columnconfigure(5,weight=1)
f1.rowconfigure(5,weight=1)
                    
f1.columnconfigure(6,weight=1)
f1.rowconfigure(6,weight=1)
                    
f1.columnconfigure(7,weight=1)
f1.rowconfigure(7,weight=1)
                    
button8 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid8')
button8.grid(row=0, column=8, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(8,weight=1)
f1.rowconfigure(8,weight=1)
                    
f1.columnconfigure(9,weight=1)
f1.rowconfigure(9,weight=1)
                    
f1.columnconfigure(10,weight=1)
f1.rowconfigure(10,weight=1)
                    
f1.columnconfigure(11,weight=1)
f1.rowconfigure(11,weight=1)
                    
button12 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid12')
button12.grid(row=1, column=3, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(12,weight=1)
f1.rowconfigure(12,weight=1)
                    
button13 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid13')
button13.grid(row=1, column=4, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(13,weight=1)
f1.rowconfigure(13,weight=1)
                    
button14 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid14')
button14.grid(row=1, column=5, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(14,weight=1)
f1.rowconfigure(14,weight=1)
                    
button15 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid15')
button15.grid(row=1, column=6, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(15,weight=1)
f1.rowconfigure(15,weight=1)
                    
button16 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid16')
button16.grid(row=1, column=7, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(16,weight=1)
f1.rowconfigure(16,weight=1)
                    
button17 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid17')
button17.grid(row=1, column=8, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(17,weight=1)
f1.rowconfigure(17,weight=1)
                    
f1.columnconfigure(18,weight=1)
f1.rowconfigure(18,weight=1)
                    
f1.columnconfigure(19,weight=1)
f1.rowconfigure(19,weight=1)
                    
f1.columnconfigure(20,weight=1)
f1.rowconfigure(20,weight=1)
                    
button21 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid21')
button21.grid(row=2, column=3, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(21,weight=1)
f1.rowconfigure(21,weight=1)
                    
button22 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid22')
button22.grid(row=2, column=4, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(22,weight=1)
f1.rowconfigure(22,weight=1)
                    
button23 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid23')
button23.grid(row=2, column=5, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(23,weight=1)
f1.rowconfigure(23,weight=1)
                    
button24 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid24')
button24.grid(row=2, column=6, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(24,weight=1)
f1.rowconfigure(24,weight=1)
                    
button25 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid25')
button25.grid(row=2, column=7, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(25,weight=1)
f1.rowconfigure(25,weight=1)
                    
button26 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid26')
button26.grid(row=2, column=8, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(26,weight=1)
f1.rowconfigure(26,weight=1)
                    
button27 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid27')
button27.grid(row=3, column=0, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(27,weight=1)
f1.rowconfigure(27,weight=1)
                    
button28 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid28')
button28.grid(row=3, column=1, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(28,weight=1)
f1.rowconfigure(28,weight=1)
                    
button29 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid29')
button29.grid(row=3, column=2, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(29,weight=1)
f1.rowconfigure(29,weight=1)
                    
button30 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid30')
button30.grid(row=3, column=3, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(30,weight=1)
f1.rowconfigure(30,weight=1)
                    
button31 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid31')
button31.grid(row=3, column=4, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(31,weight=1)
f1.rowconfigure(31,weight=1)
                    
button32 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid32')
button32.grid(row=3, column=5, padx=1, pady=1,rowspan=2,columnspan=2)

f1.columnconfigure(32,weight=1)
f1.rowconfigure(32,weight=1)
                    
f1.columnconfigure(33,weight=1)
f1.rowconfigure(33,weight=1)
                    
button34 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid34')
button34.grid(row=3, column=7, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(34,weight=1)
f1.rowconfigure(34,weight=1)
                    
button35 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid35')
button35.grid(row=3, column=8, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(35,weight=1)
f1.rowconfigure(35,weight=1)
                    
button36 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid36')
button36.grid(row=4, column=0, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(36,weight=1)
f1.rowconfigure(36,weight=1)
                    
button37 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid37')
button37.grid(row=4, column=1, padx=1, pady=1,rowspan=3,columnspan=1)

f1.columnconfigure(37,weight=1)
f1.rowconfigure(37,weight=1)
                    
button38 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid38')
button38.grid(row=4, column=2, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(38,weight=1)
f1.rowconfigure(38,weight=1)
                    
button39 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid39')
button39.grid(row=4, column=3, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(39,weight=1)
f1.rowconfigure(39,weight=1)
                    
button40 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid40')
button40.grid(row=4, column=4, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(40,weight=1)
f1.rowconfigure(40,weight=1)
                    
f1.columnconfigure(41,weight=1)
f1.rowconfigure(41,weight=1)
                    
f1.columnconfigure(42,weight=1)
f1.rowconfigure(42,weight=1)
                    
button43 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid43')
button43.grid(row=4, column=7, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(43,weight=1)
f1.rowconfigure(43,weight=1)
                    
button44 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid44')
button44.grid(row=4, column=8, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(44,weight=1)
f1.rowconfigure(44,weight=1)
                    
button45 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid45')
button45.grid(row=5, column=0, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(45,weight=1)
f1.rowconfigure(45,weight=1)
                    
f1.columnconfigure(46,weight=1)
f1.rowconfigure(46,weight=1)
                    
button47 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid47')
button47.grid(row=5, column=2, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(47,weight=1)
f1.rowconfigure(47,weight=1)
                    
button48 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid48')
button48.grid(row=5, column=3, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(48,weight=1)
f1.rowconfigure(48,weight=1)
                    
button49 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid49')
button49.grid(row=5, column=4, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(49,weight=1)
f1.rowconfigure(49,weight=1)
                    
button50 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid50')
button50.grid(row=5, column=5, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(50,weight=1)
f1.rowconfigure(50,weight=1)
                    
button51 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid51')
button51.grid(row=5, column=6, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(51,weight=1)
f1.rowconfigure(51,weight=1)
                    
button52 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid52')
button52.grid(row=5, column=7, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(52,weight=1)
f1.rowconfigure(52,weight=1)
                    
button53 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid53')
button53.grid(row=5, column=8, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(53,weight=1)
f1.rowconfigure(53,weight=1)
                    
button54 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid54')
button54.grid(row=6, column=0, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(54,weight=1)
f1.rowconfigure(54,weight=1)
                    
f1.columnconfigure(55,weight=1)
f1.rowconfigure(55,weight=1)
                    
button56 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid56')
button56.grid(row=6, column=2, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(56,weight=1)
f1.rowconfigure(56,weight=1)
                    
button57 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid57')
button57.grid(row=6, column=3, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(57,weight=1)
f1.rowconfigure(57,weight=1)
                    
button58 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid58')
button58.grid(row=6, column=4, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(58,weight=1)
f1.rowconfigure(58,weight=1)
                    
button59 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid59')
button59.grid(row=6, column=5, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(59,weight=1)
f1.rowconfigure(59,weight=1)
                    
button60 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid60')
button60.grid(row=6, column=6, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(60,weight=1)
f1.rowconfigure(60,weight=1)
                    
button61 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid61')
button61.grid(row=6, column=7, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(61,weight=1)
f1.rowconfigure(61,weight=1)
                    
button62 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid62')
button62.grid(row=6, column=8, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(62,weight=1)
f1.rowconfigure(62,weight=1)
                    
button63 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid63')
button63.grid(row=7, column=0, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(63,weight=1)
f1.rowconfigure(63,weight=1)
                    
button64 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid64')
button64.grid(row=7, column=1, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(64,weight=1)
f1.rowconfigure(64,weight=1)
                    
button65 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid65')
button65.grid(row=7, column=2, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(65,weight=1)
f1.rowconfigure(65,weight=1)
                    
button66 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid66')
button66.grid(row=7, column=3, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(66,weight=1)
f1.rowconfigure(66,weight=1)
                    
button67 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid67')
button67.grid(row=7, column=4, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(67,weight=1)
f1.rowconfigure(67,weight=1)
                    
button68 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid68')
button68.grid(row=7, column=5, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(68,weight=1)
f1.rowconfigure(68,weight=1)
                    
button69 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid69')
button69.grid(row=7, column=6, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(69,weight=1)
f1.rowconfigure(69,weight=1)
                    
button70 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid70')
button70.grid(row=7, column=7, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(70,weight=1)
f1.rowconfigure(70,weight=1)
                    
button71 = ttk.Button(f1,width=20,height=20,bd=3,command=None,text='grid71')
button71.grid(row=7, column=8, padx=1, pady=1,rowspan=1,columnspan=1)

f1.columnconfigure(71,weight=1)
f1.rowconfigure(71,weight=1)
                    

root.mainloop()

上面程序是根据用户设计布局,自动成的程序代码,程序运行结果如下图。
在这里插入图片描述
这个布局可以封装为Frame类,也就是Tkinter的控件。将grid按钮替换为用户控件,就完成了布局设计。

发布了56 篇原创文章 · 获赞 67 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/hepu8/article/details/104152053