tkinter/python:第一个GUI程序——制作一个数据录入界面

下图是在网上搜寻的一个案例图样,经过了调整修改,登录时界面图如下:

登录后点击百货店铺按钮,界面如下 

一、创建root窗口:

geometry接收一个字符串,也就是需要建立的窗口尺寸和位置,geometry('宽x高+x坐标+y坐标'),宽和高中间是英文字母x,不是中文的乘号。root.resizable(False, False)是固定窗口大小,最后需要调用root.mainloop(),保持窗口一直存在。

import tkinterroot = tkinter.Tk()
root.title('销售数据录入平台')
root.geometry('1000x660+460+100')
root.resizable(False, False)def main():root.mainloop()if __name__ == '__main__':main()

将整个root分成三个部分,一是最上面的黑色背景的顶部菜单栏控件,二是中间带图片的辅助信息控件,三是菜单栏点击后链接的下面主体控件。

二、建立顶部菜单栏控件:

顶部先用一个Frame作为容器,填充黑色背景。然后是左边是平台的名字,只需要显示,不用点击产生链接,用Label方法。后面的百货店铺、超市店铺、美食广场和登录用户是可以点击的按钮,用Button方法。Lable和Button两种方法的第一个参数都是上层容器,后面是文本、字体、前景色和背景色,然后直接调用place函数准确定位。

def head():frame = tkinter.Frame(root, bg='black')frame.place(width=1000, height=60)tkinter.Label(frame, text='销售数据录入平台', font=('黑体', 20), fg='white', bg='black').place(x=20, y=15)tkinter.Button(frame, text='百货店铺', font=('黑体', 12), fg='white', bg='black', command=body_store,relief='flat', activeforeground='grey', overrelief='raised').place(x=330, y=20)tkinter.Button(frame, text='超市店铺', font=('黑体', 12), fg='white', bg='black', command=body_supermarket,relief='flat', activeforeground='grey', overrelief='raised').place(x=490, y=20)tkinter.Button(frame, text='美食广场', font=('黑体', 12), fg='white', bg='black', command=body_food,relief='flat', activeforeground='grey', overrelief='raised').place(x=650, y=20)tkinter.Button(frame, text='用户登录', font=('黑体', 12), fg='white', bg='black', command=login,relief='flat', activeforeground='grey', overrelief='raised').place(x=810, y=20)def body_store():print('百货店铺')passdef body_supermarket():print('超市店铺')passdef body_food():print('美食广场')passdef login():print('登录用户')pass

这样就完成了菜单栏的控件布局,在main函数中增加head(),然后执行程序:

relief='flat', activeforeground='grey', overrelief='raised'三个参数分别实现效果:第一个是控制正常显示效果,第二个是按下鼠标左键时的效果,第三个是鼠标悬浮在按钮上的效果。

点击后可以看到控制台正确打印出信息:百货店铺 。

三、辅助信息控件

基本都差不多,只是增加了一个个图片的处理。

仍然是先给这部分一个单独Frame容器,填充颜色。然后是文字部分用Lable控件,其它用Button控件完成。

tkinter在处理图片的时候,如果包装到函数里面,图片就丢失了,变成了一个白块。

def information():frame = tkinter.Frame(root, bg=color)frame.place(width=940, height=140, x=30, y=100)img = tkinter.PhotoImage(file='bg1.png')tkinter.Label(frame, image=img).place(width=230, height=120, x=10, y=10)

执行结果:

网上有介绍说是执行完后图片被释放了,修改方法是再增加一条代码:tkinter.Label.image = img

def information():frame = tkinter.Frame(root, bg=color)frame.place(width=940, height=140, x=30, y=100)img = tkinter.PhotoImage(file='bg1.png')tkinter.Label(frame, image=img).place(width=230, height=120, x=10, y=10)tkinter.Label.image = img

这样确实也能实现,但是看着怪怪的的,而且在后面写登录函数再次使用这个图片时候,图片又神奇的消失了:

我想能不能在函数外部定义image呢?居然成立了。image = tkinter.PhotoImage(file='bg1.png')必须写在root = tkinter.Tk()的后面,如果写在 tkinter.Tk()前面会报错。

import tkinterroot = tkinter.Tk()
root.title('销售数据录入平台')
root.geometry('1000x660+460+100')
root.resizable(False, False)color = '#48D1CC'
image = tkinter.PhotoImage(file='bg1.png')def information():frame = tkinter.Frame(root, bg=color)frame.place(width=940, height=140, x=30, y=100)tkinter.Label(frame, image=image).place(width=230, height=120, x=10, y=10)

这种写法至少现在的情况可以完美的解决tkinter在显示图片丢失的问题。而且再次使用该图片时可以直接赋值使用,没有发生再丢失现象。完整的辅助信息栏代码:

def information():frame = tkinter.Frame(root, bg=color)frame.place(width=940, height=140, x=30, y=100)tkinter.Label(frame, image=image).place(width=230, height=120, x=10, y=10)tkinter.Label(frame, text='平台使用教程', font=('黑体', 25), fg='black', bg=color).place(x=265, y=25)tkinter.Button(frame, text='操作文档', font=('黑体', 12), fg='blue', bg=color, command=lambda: print('操作文档'),relief='flat', activeforeground='grey', overrelief='raised').place(x=520, y=37)tkinter.Button(frame, text='教学视频', font=('黑体', 12), fg='blue', bg=color, command=lambda: print('教学视频'),relief='flat', activeforeground='grey', overrelief='raised').place(x=620, y=37)tkinter.Button(frame, text='常见问题', font=('黑体', 12), fg='blue', bg=color, command=lambda: print('常见问题'),relief='flat', activeforeground='grey', overrelief='raised').place(x=720, y=37)text = '用户注册分自行注册和管理员后台注册,自行注册需确保管理员后台中注册权限已开启,\n\n点击新用户注册,填写注册信息进行注册,新入职人员需管理员后台开启权限。'tkinter.Label(frame, text=text, font=('黑体', 10), fg='black', bg=color, justify='left').place(x=265, y=83)

四、现在来写登录界面:

 登录界面需要分两部分,一个是已有用户验证密码登录,一个是新注册用户录入用户名及新密码。在弹出登录界面时,通过root.attributes('-disabled', 1)锁定根窗口,还需要调用prodocol函数,login_toplevel.protocol('WM_DELETE_WINDOW', root.quit)和根窗口建立协议,没有正常登录关闭登录窗口时关闭根窗口,否则根窗口将无法关闭了。

def login():print('登录用户')login_toplevel = tkinter.Toplevel(root)login_toplevel.title('用户登录')login_toplevel.geometry('250x200+835+400')login_toplevel.attributes('-topmost', 1)login_toplevel.resizable(False, False)login_toplevel.grab_set()login_toplevel.protocol('WM_DELETE_WINDOW', root.quit)tkinter.Label(login_toplevel, image=image).place(width=250, height=100, x=0, y=0)tkinter.Label(login_toplevel, text='用户', font=('黑体', 12)).place(width=50, height=25, x=20, y=105)tkinter.Label(login_toplevel, text='密码', font=('黑体', 12)).place(width=50, height=25, x=20, y=135)(user := tkinter.Entry(login_toplevel)).place(width=150, height=25, x=70, y=105)(password := tkinter.Entry(login_toplevel)).place(width=150, height=25, x=70, y=135)tkinter.Button(login_toplevel, text='登录', command=lambda: login_in()).place(width=100, height=30, x=20, y=165)tkinter.Button(login_toplevel, text='注册', command=lambda: register_in()).place(width=100, height=30, x=130, y=165)def login_in():print('登录')passdef register_in():print('注册')pass

这里用的海象赋值法:(:=),还挺有意思! 

 五、完善登录、注册方法

    def login_in():print('登录')if not (user.get() and password.get()):tkinter.messagebox.showerror('登录信息', '用户名或密码不能为空!', parent=login_toplevel)elif user.get() + ',' + password.get() in read_data():tkinter.messagebox.showinfo('登录信息', '登录成功', parent=login_toplevel)login_toplevel.destroy()root.attributes('-disable', 0)root.attributes('-topmost', 1)else:tkinter.messagebox.showwarning('登录信息', '用户名或密码错误!', parent=login_toplevel)def register_in():print('注册')register_toplevel = tkinter.Toplevel(root)register_toplevel.title('注册信息')register_toplevel.geometry('250x130+835+400')register_toplevel.resizable(False, False)register_toplevel.attributes('-topmost', 1)login_toplevel.attributes('-disabled', 1)register_toplevel.protocol('WM_DELETE_WINDOW', login_toplevel.quit)tkinter.Label(register_toplevel, text='新用户', font=('黑体', 12)).place(width=50, height=25, x=20, y=5)tkinter.Label(register_toplevel, text='新密码', font=('黑体', 12)).place(width=50, height=25, x=20, y=35)tkinter.Label(register_toplevel, text='新密码', font=('黑体', 12)).place(width=50, height=25, x=20, y=65)(new_user := tkinter.Entry(register_toplevel)).place(width=150, height=25, x=75, y=5)(password1 := tkinter.Entry(register_toplevel)).place(width=150, height=25, x=75, y=35)(password2 := tkinter.Entry(register_toplevel)).place(width=150, height=25, x=75, y=65)tkinter.Button(register_toplevel, text='注册', command=lambda: register_new()).place(width=100, height=30, x=20, y=95)tkinter.Button(register_toplevel, text='取消', command=lambda: register_toplevel.quit()).place(width=100, height=30, x=130, y=95)def register_new():if not (new_user.get() and password1.get()):tkinter.messagebox.showerror('注册提示', '用户名或密码不能为空!', parent=register_toplevel)elif password1.get() != password2.get():tkinter.messagebox.showerror('注册提示', '两次密码不一致!', parent=register_toplevel)else:tkinter.messagebox.showinfo('注册提示', '注册成功!', parent=register_toplevel)with open('data.csv', 'a') as file:file.write(f'{new_user.get()},{password1.get()}\n')register_toplevel.destroy()login_toplevel.attributes('-disable', 0)def read_data():with open('data.csv', 'r') as file:return map(str.strip, file.readlines())

六、补充一些百货店铺信息:

 白色的线条是用Label标签完成

def body_store():print('百货店铺')frame = tkinter.Frame(root, bg=color)frame.place(width=940, height=380, x=30, y=260)tkinter.Label(frame, bg='white').place(width=170, height=5, x=0, y=205)tkinter.Label(frame, bg='white').place(width=765, height=5, x=175, y=40)tkinter.Label(frame, bg='white').place(width=5, height=380, x=170, y=0)tkinter.Label(frame, text='销售数据', font=('黑体', 12), fg='black', bg=color).place(x=10, y=10)tkinter.Button(frame, text='批发客户管理', font=('黑体', 10), bg=color, fg='black', command=lambda: print('批发客户管理'),relief='flat', activebackground='grey', overrelief='raised').place(x=40, y=50)tkinter.Button(frame, text='销售批发管理', font=('黑体', 10), bg=color, fg='black', command=lambda: print('销售批发管理'),relief='flat', activebackground='grey', overrelief='raised').place(x=40, y=80)tkinter.Button(frame, text='批发价格管理', font=('黑体', 10), bg=color, fg='black', command=lambda: print('批发价格管理'),relief='flat', activebackground='grey', overrelief='raised').place(x=40, y=110)tkinter.Button(frame, text='批发结算管理', font=('黑体', 10), bg=color, fg='black', command=lambda: print('批发结算管理'),relief='flat', activebackground='grey', overrelief='raised').place(x=40, y=140)tkinter.Button(frame, text='批发人员管理', font=('黑体', 10), bg=color, fg='black', command=lambda: print('批发人员管理'),relief='flat', activebackground='grey', overrelief='raised').place(x=40, y=170)tkinter.Label(frame, text='数据中心', font=('黑体', 12), fg='black', bg=color).place(x=10, y=220)tkinter.Button(frame, text='销售数据查询', font=('黑体', 10), bg=color, fg='black', command=lambda: print('销售数据查询'),relief='flat', activebackground='grey', overrelief='raised').place(x=40, y=260)tkinter.Button(frame, text='库存数据查询', font=('黑体', 10), bg=color, fg='black', command=lambda: print('库存数据查询'),relief='flat', activebackground='grey', overrelief='raised').place(x=40, y=290)

七、完整代码: 

import tkinter
import tkinter.messageboxroot = tkinter.Tk()
root.title('销售数据录入平台')
root.geometry('1000x660+460+100')
root.resizable(False, False)color = '#48D1CC'
image = tkinter.PhotoImage(file='bg1.png')def information():frame = tkinter.Frame(root, bg=color)frame.place(width=940, height=140, x=30, y=100)tkinter.Label(frame, image=image).place(width=230, height=120, x=10, y=10)tkinter.Label(frame, text='平台使用教程', font=('黑体', 25), fg='black', bg=color).place(x=265, y=25)tkinter.Button(frame, text='操作文档', font=('黑体', 12), fg='blue', bg=color, command=lambda: print('操作文档'),relief='flat', activeforeground='grey', overrelief='raised').place(x=520, y=37)tkinter.Button(frame, text='教学视频', font=('黑体', 12), fg='blue', bg=color, command=lambda: print('教学视频'),relief='flat', activeforeground='grey', overrelief='raised').place(x=620, y=37)tkinter.Button(frame, text='常见问题', font=('黑体', 12), fg='blue', bg=color, command=lambda: print('常见问题'),relief='flat', activeforeground='grey', overrelief='raised').place(x=720, y=37)text = '用户注册分自行注册和管理员后台注册,自行注册需确保管理员后台中注册权限已开启,\n\n点击新用户注册,填写注册信息进行注册,新入职人员需管理员后台开启权限。'tkinter.Label(frame, text=text, font=('黑体', 10), fg='black', bg=color, justify='left').place(x=265, y=83)def head():frame = tkinter.Frame(root, bg='black')frame.place(width=1000, height=60)tkinter.Label(frame, text='销售数据录入平台', font=('黑体', 20), fg='white', bg='black').place(x=20, y=15)tkinter.Button(frame, text='百货店铺', font=('黑体', 12), fg='white', bg='black', command=body_store,relief='flat', activeforeground='grey', overrelief='raised').place(x=330, y=20)tkinter.Button(frame, text='超市店铺', font=('黑体', 12), fg='white', bg='black', command=body_supermarket,relief='flat', activeforeground='grey', overrelief='raised').place(x=490, y=20)tkinter.Button(frame, text='美食广场', font=('黑体', 12), fg='white', bg='black', command=body_food,relief='flat', activeforeground='grey', overrelief='raised').place(x=650, y=20)tkinter.Button(frame, text='用户登录', font=('黑体', 12), fg='white', bg='black', command=login,relief='flat', activeforeground='grey', overrelief='raised').place(x=810, y=20)def body_store():print('百货店铺')frame = tkinter.Frame(root, bg=color)frame.place(width=940, height=380, x=30, y=260)tkinter.Label(frame, bg='white').place(width=170, height=5, x=0, y=205)tkinter.Label(frame, bg='white').place(width=765, height=5, x=175, y=40)tkinter.Label(frame, bg='white').place(width=5, height=380, x=170, y=0)tkinter.Label(frame, text='销售数据', font=('黑体', 12), fg='black', bg=color).place(x=10, y=10)tkinter.Button(frame, text='批发客户管理', font=('黑体', 10), bg=color, fg='black', command=lambda: print('批发客户管理'),relief='flat', activebackground='grey', overrelief='raised').place(x=40, y=50)tkinter.Button(frame, text='销售批发管理', font=('黑体', 10), bg=color, fg='black', command=lambda: print('销售批发管理'),relief='flat', activebackground='grey', overrelief='raised').place(x=40, y=80)tkinter.Button(frame, text='批发价格管理', font=('黑体', 10), bg=color, fg='black', command=lambda: print('批发价格管理'),relief='flat', activebackground='grey', overrelief='raised').place(x=40, y=110)tkinter.Button(frame, text='批发结算管理', font=('黑体', 10), bg=color, fg='black', command=lambda: print('批发结算管理'),relief='flat', activebackground='grey', overrelief='raised').place(x=40, y=140)tkinter.Button(frame, text='批发人员管理', font=('黑体', 10), bg=color, fg='black', command=lambda: print('批发人员管理'),relief='flat', activebackground='grey', overrelief='raised').place(x=40, y=170)tkinter.Label(frame, text='数据中心', font=('黑体', 12), fg='black', bg=color).place(x=10, y=220)tkinter.Button(frame, text='销售数据查询', font=('黑体', 10), bg=color, fg='black', command=lambda: print('销售数据查询'),relief='flat', activebackground='grey', overrelief='raised').place(x=40, y=260)tkinter.Button(frame, text='库存数据查询', font=('黑体', 10), bg=color, fg='black', command=lambda: print('库存数据查询'),relief='flat', activebackground='grey', overrelief='raised').place(x=40, y=290)def body_supermarket():print('超市店铺')frame = tkinter.Frame(root, bg=color)frame.place(width=940, height=380, x=30, y=260)tkinter.Label(frame, bg='white').place(width=170, height=5, x=0, y=205)tkinter.Label(frame, bg='white').place(width=765, height=5, x=175, y=40)tkinter.Label(frame, bg='white').place(width=5, height=380, x=170, y=0)def body_food():print('美食广场')frame = tkinter.Frame(root, bg=color)frame.place(width=940, height=380, x=30, y=260)tkinter.Label(frame, bg='white').place(width=170, height=5, x=0, y=205)tkinter.Label(frame, bg='white').place(width=765, height=5, x=175, y=40)tkinter.Label(frame, bg='white').place(width=5, height=380, x=170, y=0)def login():print('登录用户')login_toplevel = tkinter.Toplevel(root)login_toplevel.title('用户登录')login_toplevel.geometry('250x200+835+400')login_toplevel.attributes('-topmost', 1)login_toplevel.resizable(False, False)login_toplevel.grab_set()login_toplevel.protocol('WM_DELETE_WINDOW', root.quit)tkinter.Label(login_toplevel, image=image).place(width=250, height=100, x=0, y=0)tkinter.Label(login_toplevel, text='用户', font=('黑体', 12)).place(width=50, height=25, x=20, y=105)tkinter.Label(login_toplevel, text='密码', font=('黑体', 12)).place(width=50, height=25, x=20, y=135)(user := tkinter.Entry(login_toplevel)).place(width=150, height=25, x=70, y=105)(password := tkinter.Entry(login_toplevel)).place(width=150, height=25, x=70, y=135)tkinter.Button(login_toplevel, text='登录', command=lambda: login_in()).place(width=100, height=30, x=20, y=165)tkinter.Button(login_toplevel, text='注册', command=lambda: register_in()).place(width=100, height=30, x=130, y=165)def login_in():print('登录')if not (user.get() and password.get()):tkinter.messagebox.showerror('登录信息', '用户名或密码不能为空!', parent=login_toplevel)elif user.get() + ',' + password.get() in read_data():tkinter.messagebox.showinfo('登录信息', '登录成功', parent=login_toplevel)login_toplevel.destroy()root.attributes('-disable', 0)root.attributes('-topmost', 1)else:tkinter.messagebox.showwarning('登录信息', '用户名或密码错误!', parent=login_toplevel)def register_in():print('注册')register_toplevel = tkinter.Toplevel(root)register_toplevel.title('注册信息')register_toplevel.geometry('250x130+835+400')register_toplevel.resizable(False, False)register_toplevel.attributes('-topmost', 1)login_toplevel.attributes('-disabled', 1)register_toplevel.protocol('WM_DELETE_WINDOW', login_toplevel.quit)tkinter.Label(register_toplevel, text='新用户', font=('黑体', 12)).place(width=50, height=25, x=20, y=5)tkinter.Label(register_toplevel, text='新密码', font=('黑体', 12)).place(width=50, height=25, x=20, y=35)tkinter.Label(register_toplevel, text='新密码', font=('黑体', 12)).place(width=50, height=25, x=20, y=65)(new_user := tkinter.Entry(register_toplevel)).place(width=150, height=25, x=75, y=5)(password1 := tkinter.Entry(register_toplevel)).place(width=150, height=25, x=75, y=35)(password2 := tkinter.Entry(register_toplevel)).place(width=150, height=25, x=75, y=65)tkinter.Button(register_toplevel, text='注册', command=lambda: register_new()).place(width=100, height=30, x=20, y=95)tkinter.Button(register_toplevel, text='取消', command=lambda: register_toplevel.quit()).place(width=100, height=30, x=130, y=95)def register_new():if not (new_user.get() and password1.get()):tkinter.messagebox.showerror('注册提示', '用户名或密码不能为空!', parent=register_toplevel)elif password1.get() != password2.get():tkinter.messagebox.showerror('注册提示', '两次密码不一致!', parent=register_toplevel)else:tkinter.messagebox.showinfo('注册提示', '注册成功!', parent=register_toplevel)with open('data.csv', 'a') as file:file.write(f'{new_user.get()},{password1.get()}\n')register_toplevel.destroy()login_toplevel.attributes('-disable', 0)def read_data():with open('data.csv', 'r') as file:return map(str.strip, file.readlines())def main():head()information()login()root.mainloop()if __name__ == '__main__':main()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3015016.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

字符设备驱动流程

字符设备驱动: linux系统驱动程序分为三大类,字符设备驱动,块设备驱动和网络设备驱动。其中字符设备驱动是使用最多的一种,从点灯到llC,SPI,音频设备等的驱动都是字符设备驱动。块设备和网络设备驱动要比字…

使用fitten code插件(vscode),替换通义千问,识别需求中的输入输出

今天我们介绍一个工具,具体介绍可以参考我的这篇文章的介绍,支持vs code 插件,Fitten Code是一款由非十科技开发的AI代码助手,旨在通过大模型驱动来提升编程效率和体验-免费神器-CSDN博客https://blog.csdn.net/lijigang100/article/details/137833223?spm=1001.2014.3001…

超越传统游戏:生成式人工智能对游戏的变革性影响

人工智能(AI)在游戏中的应用 游戏产业是一个充满活力、不断发展的领域,人工智能(AI)的融入对其产生了重大影响。这一技术进步彻底改变了游戏的开发、玩法和体验方式。本文分析的重点是传统人工智能和生成式人工智能在游…

【Java笔记】多线程:中断

线程中断的作用 线程中断可以使一个线程从等待状态变成就绪状态 使用线程中断,并不是要把线程给终止或是杀死,而是让线程不再继续等待,而是让线程不再继续等待,线程可以继续往下执行代码,线程发生中断后,会…

Linux网络编程(二) socket编程及其仿真

本节内容介绍Linux下进行网络编程所必须得socket接口的一些知识 一、socket地址函数 1.1、主机字节序和网络字节序 现代PC大多采用小端字节序,因此小端字节序又被称为主机字节序。 为了避免由于字节序导致的错误,发送端总是将字节序转换为大端字节序…

暖心又实用!母亲节教会妈妈这4招才是最贴心的礼物

母亲节就要到了,这个特殊的日子,我们总是想要为妈妈送上最真挚的祝福和关怀。在这个数字化时代,一部智能手机就能成为我们表达爱意的桥梁。今天,就让我们一起来看看华为手机的四个功能,让妈妈的手机使用体验更加便捷、…

C语言中的关键字static和extern

Hello,亲爱的小伙伴们,我又来了,上一期作者菌讲解了C语言中函数的知识点,得到了很好的反馈,这里作者菌感谢每一个至此我的小伙伴!!今天作者菌又来补充一些很有用的知识,感兴趣的uu们不要吝啬手中…

Jmeter 命令行压测 生成 HTML 测试报告,你真的会?

通常 Jmeter 的 GUI 模式仅用于调试,在实际的压测项目中,为了让压测机有更好的性能,多用 Jmeter 命令行来进行压测。 同时,JMeter 也支持生成 HTML 测试报告, 以便从测试计划中获得图表和统计信息。 以上定义的文件路…

Elementui的el-footer标签使用报错

Elementui的el-footer标签使用报错 其余标签的使用没有报错信息 el-footer的报错信息 原因: ​ 警告信息表示 Vue 不识别 <el-footer> 解决方式: 在组件中进行引入和暴露

Flume 的安装和使用方法

一、Flume的安装 1.下载压缩包 https://www.apache.org/dyn/closer.lua/flume/1.7.0/apache-flume-1.7.0-bin.tar.gz 2.上传到linux中 3.解压安装包 cd #进入加载压缩包目录sudo tar -zxvf apache-flume-1.7.0-bin.tar.gz -C /usr/local # 将 apache-flume-1.7.0-bin.tar.g…

119. 再谈接口幂等性

文章目录 0. 前言1. insert前先select2. 加悲观锁3. 加乐观锁5. 加唯一索引【配合 &#xff08;1. insert前先select &#xff09;最常用 】6. 建防重表6. 根据状态机7. 加分布式锁8. 获取token 0. 前言 在 93. 通用防重幂等设计 一文中&#xff0c;已经介绍过幂等的使用。该文…

力扣:63. 不同路径 II

63. 不同路径 II 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那么…

C# Web控件与数据感应之 BaseDataList 类

目录 关于数据感应 BaseDataList 类 范例运行环境 pageview 方法 设计 实现 调用示例 数据源 调用 小结 关于数据感应 数据感应也即数据捆绑&#xff0c;是一种动态的&#xff0c;Web控件与数据源之间的交互&#xff0c;本文将继续介绍以与数据库提取数据并捆绑控件…

CI522/CI523电动车NFC一键启动开发资料

Ci522是一颗工作在13.56MHz频率下的非接触式读写芯片&#xff0c;支持读A卡&#xff08;CI523支持读A/B卡&#xff09;&#xff0c;可做智能门锁、电动车NFC一键启动、玩具NFC开锁等应用。为部分要求低成本&#xff0c;PCB小体积的产品提供了可靠的选择。 Ci522与Si522/MFRC52…

第3章 WebServer重构

3.1 重构原生Web服务框架 3.1.1 分析原生Web服务框架 在服务端代码的 ClientHandler 中&#xff0c;请求解析、处理请求、返回响应的代码混杂在一起&#xff0c;这样的设计会导致代码难以维护和理解。为了提高代码的可读性、可维护性和可扩展性&#xff0c;我们需要对这些代码…

UDP广播

1、UDP广播 1.1、广播的概念 广播&#xff1a;由一台主机向该主机所在子网内的所有主机发送数据的方式 例如 &#xff1a;192.168.3.103主机发送广播信息&#xff0c;则192.168.3.1~192.168.3.254所有主机都可以接收到数据 广播只能用UDP或原始IP实现&#xff0c;不能用TCP…

漏洞挖掘 | EDU证书站任意密码重置

1.前言&#xff1a; 挖了一段时间EDU老破小的站&#xff0c;也该拿证书站下手了。下手的第一个目标&#xff0c;那必然是漏洞排行榜第一的某交大&#xff01;&#xff01;&#xff01; 2.信息搜集 想快速挖到漏洞&#xff0c;必须信息搜集全面。如果信息搜集不到位不全面&…

明星中药企业系列洞察(二)丨百年御药同仁堂,为什么被称为我国最“硬”的老字号?

从最初的同仁堂药室、同仁堂药店到现在的北京同仁堂集团&#xff0c;经历了清王朝由强盛到衰弱、几次外敌入侵、军阀混战到新民主主义革命的历史沧桑&#xff0c;其所有制形式、企业性质、管理方式也都发生了根本性的变化&#xff0c;但同仁堂经历数代而不衰&#xff0c;在海内…

蓝桥杯练习系统(算法训练)ALGO-947 贫穷的城市

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 某城市有n个小镇&#xff0c;编号是1~n。由于贫穷和缺乏城市规划的人才&#xff0c;每个小镇有且仅有一段单向的公路通往别…