tkinter Listbox 列表框实现多列对齐排列并绑定下拉框和滚动条

news2024/11/30 2:34:28

 


from tkinter import *
from tkinter import ttk, Button, Canvas, Listbox, Entry, LabelFrame, IntVar, Checkbutton, messagebox

import win32print
root = Tk()
root.title("tkinter Listbox 列表框实现多列对齐排列")
root.geometry('550x450')


def callback2(t, event=None):
    # 复制操作
    t.event_generate('<<Copy>>')


def popup(top, t, event=None):
    menu = Menu(top, tearoff=False)
    menu.add_command(label="复制", command=lambda *e: callback2(t))
    menu.post(event.x_root, event.y_root)  # post在指定的位置显示弹出菜单


def delete_item(listbox, all_data_dic0, printers_valus2):
    # 获取Listbox中所有被选中的项目
    selected_items = listbox.curselection()
    # 对选中的项目进行逆序排列,以免删除项目影响后面的索引
    # selected_items.reverse()
    item = selected_items[0]
    temp_value = listbox.get(item)
    # listbox.delete(item)
    if messagebox.askokcancel("删除", "确定删除吗?"):
        temp_value2 = all_data_dic0[item]
        delete_sql = f'delete from data_table where byname="%s"'
        # link.insert_one(delete_sql % temp_value2['Name0'])
        # register_form(printers_valus2=printers_valus2) # 刷新页面


def on_entry_click(event, entry, default_value):
    # 鼠标点击输入框
    if entry.get() == default_value:
        # entry.delete(0, END)
        pass
    else:
        print(f'entry.get():{entry.get()} default_value:{default_value}')


def on_mouse_leave(event, entry, default_value):
    # 鼠标离开事件
    if not entry.get().strip():
        entry.delete(0, END)
        entry.insert(0, default_value)


def on_entry_clicked1(entry0, entry2, pos_name, printers_valus2, item_value1, new_child_window, listbox, item):
    # 保存修改数据
    byname = entry0.get().strip()
    sizename = entry2.get().strip()
    printername = pos_name.get()
    byname_old = item_value1['Name0']
    is_update = False
    search_sql = 'select id from data_table where byname="%s" and sizename="%s" and printername="%s"'
    # exist = link.one_search(search_sql % (byname, sizename, printername), "data_table")
    # print('exist:', exist)
    # if exist:
    #     print('此名称0已经存在')
    #     notification.notify(title='此名称0已经存在', message='此名称0已经存在', timeout=5)
    #     is_update = False
    # else:
    #     is_update = True
    #
    # if is_update:
    #     update_sql = f'update data_table set byname="%s",sizename="%s",printername="%s" where byname="%s"'
    #     # print(update_sql % (byname, sizename, printername, byname_old))
    #     link.insert_one(update_sql % (byname, sizename, printername, byname_old))
    #     register_form(printers_valus2=printers_valus2) # 刷新页面
    new_child_window.destroy()


def on_entry_clicked2(entry0, entry2, pos_name, printers_valus2, new_child_window):
    # 保存新增数据
    byname = entry0.get().strip()
    sizename = entry2.get().strip()
    printername = pos_name.get()
    search_sql = 'select id from data_table where byname="%s" and sizename="%s" and printername="%s"'
    # exist = link.one_search(search_sql % (byname, sizename, printername), "data_table")
    # if exist:
    #     print('此名称0已经存在')
    #     notification.notify(title='此名称0已经存在', message='此名称0已经存在', timeout=5)
    # else:
    #     sql = 'insert into data_table(byname, sizename, printername) values(%r,%r,%r)'
    #     link.insert_one(sql % (byname, sizename, printername))
    #     register_form(printers_valus2=printers_valus2)
    new_child_window.destroy()


def create_frame(printers_valus2, event):
    # 创建一个新的Frame
    new_child_window = Toplevel()
    new_child_window.title('新增')
    # new_child_window.iconphoto(False, PhotoImage(data=iconphoto_path)) # 图标
    new_child_window.geometry(f'280x180+{event.x_root}+{event.y_root}')  # menu.post(event.x_root, event.y_root)

    label1 = Label(new_child_window, text='名称0:')
    label1.place(relx=0, rely=0.02, relheight=0.2, relwidth=0.55)
    entry0 = Entry(new_child_window, textvariable='name0')
    entry0.place(relx=0.46, rely=0.02, relheight=0.2, relwidth=0.45)
    # 插入默认值
    entry0.delete(0, END)
    entry0.insert(0, '名称1')
    # 绑定点击事件
    entry0.bind("<Button-1>", lambda event: on_entry_click(event, entry0, '名称1'))
    entry0.bind("<Leave>", lambda event: on_mouse_leave(event, entry0, '名称1'))

    label2 = Label(new_child_window, text='名称1:')
    label2.place(relx=0, rely=0.24, relheight=0.2, relwidth=0.55)
    entry2 = Entry(new_child_window, textvariable='name2')
    entry2.place(relx=0.46, rely=0.24, relheight=0.2, relwidth=0.45)
    # 插入默认值
    entry2.delete(0, END)
    entry2.insert(0, "70*50")
    # 绑定点击事件
    entry2.bind("<Button-1>", lambda event: on_entry_click(event, entry2, "70*50"))
    entry2.bind("<Leave>", lambda event: on_mouse_leave(event, entry2, "70*50"))

    # 选择名称2
    label3 = Label(new_child_window, text='选择名称2:', bd=3, width=16)
    label3.place(relx=0, rely=0.46, relwidth=0.55, relheight=0.2)

    # 获取默认打印机名称
    show_device_name = win32print.GetDefaultPrinter()
    if show_device_name not in printers_valus2:
        show_device_name = printers_valus2[0]

    # 下拉框
    pos_name = ttk.Combobox(new_child_window, width=20, height=10, textvariable=show_device_name, state='readonly')
    # 设置Combobox的下拉选项
    pos_name['values'] = printers_valus2
    pos_name.place(relx=0.46, rely=0.46, relwidth=0.45, relheight=0.2)

    if show_device_name in printers_valus2:
        pos_name.current(printers_valus2.index(show_device_name))
    else:
        pos_name.current(0)
    # 保存新增的数据
    confirm_btn = Button(new_child_window, text='确认', width=10,
                         command=lambda: on_entry_clicked2(entry0, entry2, pos_name, printers_valus2,
                                                                new_child_window))
    confirm_btn.place(relx=0.3, rely=0.72, relheight=0.2, relwidth=0.35)


def edit_frame(event, item, all_data_dic0, printers_valus2, listbox):
    # 创建一个新的Frame
    item_value = listbox.get(item)
    # print('item_value:', item_value)
    # print('item_value1:', all_data_dic0[item])
    item_value1 = all_data_dic0[item]

    new_child_window = Toplevel()
    new_child_window.title('编辑')
    # new_child_window.iconphoto(False, PhotoImage(data=iconphoto_path))  # 设置图标
    new_child_window.geometry(f'280x180+{event.x_root}+{event.y_root}')  # menu.post(event.x_root, event.y_root)

    label1 = Label(new_child_window, text='名称0:')
    label1.place(relx=0, rely=0.02, relheight=0.2, relwidth=0.55)
    entry0 = Entry(new_child_window, textvariable='name0')
    entry0.place(relx=0.46, rely=0.02, relheight=0.2, relwidth=0.45)
    # 插入默认值
    entry0.delete(0, END)
    entry0.insert(0, item_value1['Name0'])
    # 绑定点击事件
    entry0.bind("<Button-1>", lambda event: on_entry_click(event, entry0, item_value1['Name0']))
    entry0.bind("<Leave>", lambda event: on_mouse_leave(event, entry0, item_value1['Name0']))

    label2 = Label(new_child_window, text='名称1:')
    label2.place(relx=0, rely=0.24, relheight=0.2, relwidth=0.55)
    entry2 = Entry(new_child_window, textvariable='name2')
    entry2.place(relx=0.46, rely=0.24, relheight=0.2, relwidth=0.45)
    # 插入默认值
    entry2.delete(0, END)
    entry2.insert(0, item_value1['Name'])
    # 绑定点击事件
    entry2.bind("<Button-1>", lambda event: on_entry_click(event, entry2, item_value1['Name']))
    entry2.bind("<Leave>", lambda event: on_mouse_leave(event, entry2, item_value1['Name']))

    # 选择名称2
    label3 = Label(new_child_window, text='选择名称2:', bd=3, width=16)
    label3.place(relx=0, rely=0.46, relwidth=0.55, relheight=0.2)

    # 获取默认打印机设备
    show_device_name = item_value1['Name2']

    # 下拉框
    pos_name = ttk.Combobox(new_child_window, width=20, height=10, textvariable=show_device_name, state='readonly')
    printers_temp = ['OneNote for Windows 10', '导出为WPS PDF', 'Microsoft XPS Document Writer',
                     'Microsoft Print to PDF', 'Fax']
    # 设置Combobox的下拉选项
    pos_name['values'] = printers_valus2
    pos_name.place(relx=0.46, rely=0.46, relwidth=0.45, relheight=0.2)

    if show_device_name in printers_valus2:
        pos_name.current(printers_valus2.index(show_device_name))
    else:
        pos_name.current(0)
    # 保存修改的数据
    confirm_btn = Button(new_child_window, text='确认', width=10,
                         command=lambda: on_entry_clicked1(entry0, entry2, pos_name, printers_valus2, item_value1,
                                                                new_child_window, listbox, item))
    confirm_btn.place(relx=0.3, rely=0.72, relheight=0.2, relwidth=0.35)


def get_display_width(s):
    width = 0
    for char in s:
        width += len(char.encode(sys.stdout.encoding))
    return width


def show_menu(listbox, all_data_dic0, printers_valus2, event, top=None):
    # 根据当前位置获取Listbox中选中的项目
    try:
        item = listbox.curselection()[0]
    except IndexError:
        item = 0

    # 创建菜单,并添加选项
    menu = Menu(top, tearoff=0)
    if item > 0:
        menu.add_command(label="删除", command=lambda: delete_item(listbox, all_data_dic0, printers_valus2))
        menu.add_separator()  # 分割线
        menu.add_command(label="编辑",
                         command=lambda: edit_frame(event, item, all_data_dic0, printers_valus2, listbox))
        menu.add_separator()  # 分割线
        menu.add_command(label="复制", command=lambda: callback2(listbox))
        menu.add_separator()  # 分割线
    # 如果选中了项目,就在菜单中显示项目的值
    if item or item == 0:
        menu.add_command(label="增加", command=lambda: create_frame(printers_valus2, event))
    # 在相应位置显示菜单
    menu.post(event.x_root, event.y_root)


def show_listbox(printers_valus2, select_value=None):
    # 展示列表框内容
    scrollbar = Scrollbar(root)
    scrollbar.place(relx=0.85, rely=0.52, relheight=0.46, relwidth=0.035)

    listbox = Listbox(root, width=90, font='TkDefaultFont 11')
    listbox.place(relx=0.1, rely=0.52, relheight=0.46, relwidth=0.75)
    # 1. 从 sqlite3 中 读取数据
    # if not select_value or select_value == '全部':
    #     all_data = link.all_search('select byname,sizename,printername from data_table', 'data_table')
    # else:
    #     all_data = link.all_search(
    #         'select byname,sizename,printername from data_table where printername="%s"' % select_value, 'data_table')
    # allStudents = [{'Name0': i[0], 'Name': i[1], 'Name2': i[2]} for i in all_data]
    # 2. 测试数据
    allStudents_all = [{'Name0': 'USER', 'Name': '1041*1524', 'Name2': 'TSC TTP-244 Pro'},
                   {'Name0': '100*100', 'Name': '1025*1000', 'Name2': 'TSC TTP-244 Pro'},
                   {'Name0': '100*150', 'Name': '1025*1500', 'Name2': 'TSC TTP-244 Pro'},
                   {'Name0': '100x100', 'Name': '250*150', 'Name2': 'TSC TTP-244 Pro'},
                   {'Name0': '111', 'Name': '876*700', 'Name2': 'TSC TTP-244 Pro'},
                   {'Name0': '2 x 4', 'Name': '533*1016', 'Name2': 'TSC TTP-244 Pro'},
                   {'Name0': '4 x 4', 'Name': '1041*1016', 'Name2': 'TSC TTP-244 Pro'},
                   {'Name0': '4 x 6', 'Name': '1041*1524', 'Name2': 'TSC TTP-244 Pro'},
                   {'Name0': '45*30', 'Name': '475*300', 'Name2': 'TSC TTP-244 Pro'},
                   {'Name0': '50*30', 'Name': '525*300', 'Name2': 'TSC TTP-244 Pro'},
                   {'Name0': '70*30', 'Name': '725*300', 'Name2': 'TSC TTP-244 Pro'},
                   {'Name0': '70*50', 'Name': '725*500', 'Name2': 'TSC TTP-244 Pro'},
                   {'Name0': '新卷', 'Name': '525*300', 'Name2': 'TSC TTP-244 Pro'},
                   {'Name0': '名称1', 'Name': '676*300', 'Name2': 'TSC TTP-244 Pro'},
                   {'Name0': '名称2', 'Name': '1026*1500', 'Name2': 'TSC TTP-244 Pro'},
                   {'Name0': 'USER', 'Name': '1041*1016', 'Name2': 'Gprinter GP-1324D'},
                   {'Name0': '100*100', 'Name': '1025*1000', 'Name2': 'Gprinter GP-1324D'},
                   {'Name0': '100*150', 'Name': '1025*1500', 'Name2': 'Gprinter GP-1324D'},
                   {'Name0': '100x100', 'Name': '250*150', 'Name2': 'Gprinter GP-1324D'},
                   {'Name0': '111', 'Name': '876*700', 'Name2': 'Gprinter GP-1324D'},
                   {'Name0': '2 x 4', 'Name': '533*1016', 'Name2': 'Gprinter GP-1324D'},
                   {'Name0': '4 x 4', 'Name': '1041*1016', 'Name2': 'Gprinter GP-1324D'},
                   {'Name0': '4 x 6', 'Name': '1041*1524', 'Name2': 'Gprinter GP-1324D'},
                   {'Name0': '45*30', 'Name': '475*300', 'Name2': 'Gprinter GP-1324D'},
                   {'Name0': '50*30', 'Name': '525*300', 'Name2': 'Gprinter GP-1324D'},
                   {'Name0': '70*30', 'Name': '725*300', 'Name2': 'Gprinter GP-1324D'},
                   {'Name0': '70*50', 'Name': '725*500', 'Name2': 'Gprinter GP-1324D'},
                   {'Name0': '新卷', 'Name': '525*300', 'Name2': 'Gprinter GP-1324D'},
                   {'Name0': '名称1', 'Name': '676*300', 'Name2': 'Gprinter GP-1324D'},
                   {'Name0': '名称2', 'Name': '1026*1500', 'Name2': 'Gprinter GP-1324D'}]
    if not select_value or select_value == '全部':
        allStudents = allStudents_all
    else:
        allStudents = []
        for i in allStudents_all:
            if select_value in i['Name2']:
                allStudents.append(i)

    maxspace0 = get_display_width(max(allStudents, key=lambda x: get_display_width(x['Name0']))['Name0']) + 4
    maxspace = get_display_width(max(allStudents, key=lambda x: get_display_width(x['Name']))['Name']) + 4
    # 一个汉字占两个字符
    listbox.insert(END, f"{'名称0'.ljust(maxspace0 - 2)}  {'名称1'.ljust(maxspace - 2)}  名称2")
    all_data_dic0 = {}
    for i in range(len(allStudents)):
        tem = 0
        for l in allStudents[i]['Name0']:
            if get_display_width(l) > 1:
                tem += 1
        tem1 = 0
        for l1 in allStudents[i]['Name']:
            if get_display_width(l1) > 1:
                tem1 += 1
        text1 = f"{allStudents[i]['Name0'].ljust(maxspace0 - tem)}  {allStudents[i]['Name'].ljust(maxspace - tem1)}  {allStudents[i]['Name2']}"
        listbox.insert(END, text1)
        all_data_dic0[i + 1] = allStudents[i]
    listbox.configure(yscrollcommand=scrollbar.set)
    scrollbar.configure(command=listbox.yview)

    # 左键点击列表框中的值, 并执行后续操作
    # listbox.bind('<<ListboxSelect>>', lambda event: listbox_select(listbox.curselection(), listbox, event, all_data_dic, combobox, printers_valus2))
    # 绑定右键菜单
    listbox.bind("<Button-3>",
                 lambda event: show_menu(listbox, all_data_dic0, printers_valus2, event))


def update_listbox(event, printers_valus2, select_value):
    # 更新列表框的内容
    print('select_value:', select_value)
    show_listbox(printers_valus2, select_value)


def register_form(printers_valus2=None):
    # 销毁所有滚动条和列表框
    # 与下拉框内容绑定
    combobox6 = ttk.Combobox(root, width=20, height=10)
    printers_temp = ['OneNote for Windows 10', '导出为WPS PDF', 'Microsoft XPS Document Writer', 'Microsoft Print to PDF',
                     'Fax']
    printers_valus3 = list(set(printers_valus2).difference(set(printers_temp)))
    printers_valus3.insert(0, '全部')
    print('printers_valus3:', printers_valus3)
    # 设置Combobox的下拉选项
    combobox6['values'] = printers_valus3
    combobox6.bind("<<ComboboxSelected>>", lambda event: update_listbox(event, printers_valus2, combobox6.get()))
    combobox6.place(relx=0.1, rely=0.43, relheight=0.08, relwidth=0.75)
    try:
        combobox6.current(0)
    except:
        pass
    # 展示列表框内容
    show_listbox(printers_valus2)


register_form(['Gprinter GP-1324D', 'TSC TTP-244 Pro'])


mainloop()

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

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

相关文章

k8s-对命名空间资源配额

对k8s命名空间限制的方法有很多种&#xff0c;今天来演示一下很常用的一种 用的k8s对象就是ResourceQuota 一&#xff1a;创建命名空间 kubectl create ns test #namespace命名空间可以简写成ns 二&#xff1a; 对命名空间进行限制 创建resourcequota vim resourcequ…

Http请求转发服务器实现

Http请求转发服务器实现 需求场景 云服务器通过VPN连接了现场的n台工控机&#xff0c;每台工控机上都在跑web程序&#xff0c;现在我想通过公网直接访问工控机上的web服务&#xff0c;给客户查看现场的具体运行情况&#xff0c;而不是让客户再装一个VPN&#xff0c;简化操作。…

Axure重要元件三——中继器函数

亲爱的小伙伴&#xff0c;在您浏览之前&#xff0c;烦请关注一下&#xff0c;在此深表感谢&#xff01; 课程主题&#xff1a;中继器函数 主要内容&#xff1a;Item、Reperter、TargetItem 1、中继器的函数&#xff1a;Item\Reperter\TargetItem Item item&#xff1a;获取…

【UE5】将2D切片图渲染为体积纹理,最终实现使用RT实时绘制体积纹理【第五篇-着色器投影-投射阴影部分】

投射阴影 最初打算将投影内容放在上一篇中&#xff0c;因为实现非常快速简单&#xff0c;没必要单独成篇。不过因为这里面涉及一些问题&#xff0c;我觉得还是单独作为一篇讲一下比较好。 原理 这里要用到的是 Shadow Pass Switch ,它可以为非不透明的材质替换阴影 某些版本…

ubuntu22.04下GStreamer源码编译单步调试

前言 本文会通过介绍在linux平台下的GStreamer的源码编译和单步调试example实例。官网介绍直接通过命令行来安装gstreamer可以参考链接&#xff1a;Installing on Linux。 这种方法安装后&#xff0c;基于gstreamer的程序&#xff0c;单步调试的时候并不会进入到gstreamer源码…

架构师:Nginx 实现负载均衡的技术指南

1、简述 NGINX 是一种高性能的 HTTP 服务器和反向代理服务器,广泛应用于 web 服务器场景中。负载均衡是 NGINX 的重要功能之一,能够将请求分发到多个服务器上,提高应用的可用性和性能。 NGINX 负载均衡的主要策略: 轮询 (Round Robin): 将请求依次分发到后端服务器,每个…

中国移动机器人将投入养老场景;华为与APUS共筑AI医疗多场景应用

AgeTech News 一周行业大事件 华为与APUS合作&#xff0c;共筑AI医疗多场景应用 中国移动展出人形机器人&#xff0c;预计投入养老等场景 作为科技与奥富能签约&#xff0c;共拓智能适老化改造领域 天与养老与香港科技园&#xff0c;共探智慧养老新模式 中山大学合作中国…

Web应用程序的设计与前端开发

我们的客户专门从事自动化系统的开发和支持&#xff0c;用于分析、报告、规划和其他业务任务&#xff0c;以及集成外部产品。 任务 我们的客户开始开发一个用于企业业务分析的web应用程序。他们自己处理后端&#xff0c;而我们的团队负责界面和前端。界面不仅在视觉上具有吸引…

论文阅读(十六):Deep Residual Learning for Image Recognition

文章目录 1.介绍2.基本原理3.两种残差块4.网络结构 论文&#xff1a;Deep Residual Learning for Image Recognition   论文链接&#xff1a;Deep Residual Learning for Image Recognition   代码链接&#xff1a;Github 1.介绍 在ResNet网络提出之前&#xff0c;传统的卷…

医疗领域的RAG技术:如何通过知识图谱提升准确性

在医学领域&#xff0c;准确的信息检索和处理至关重要。随着大型语言模型&#xff08;LLMs&#xff09;的兴起&#xff0c;检索增强生成&#xff08;RAG&#xff09;技术在医学信息处理中的应用越来越受到关注。本文将探讨RAG技术在医学领域的应用&#xff0c;特别是如何利用知…

动态规划 - 完全背包问题

文章目录 题目描述题解思路题解代码 题目描述 题解思路 完全背包问题和01背包问题不同的地方就是完全背包问题中每个物品能选无数次&#xff0c;而01背包问题中每个物品最多只能选择一次 如果你还没有学过01背包&#xff0c;请先看这篇博客学习01背包&#xff1a;https://blo…

基于Javaweb的医院挂号预约管理系统

系统展示 用户前台界面 管理员后台界面 医生后台界面 系统背景 在现代社会&#xff0c;随着医疗需求的不断增长&#xff0c;病患挂号成为医院面临的一大挑战。传统的挂号方式不仅耗时耗力&#xff0c;还容易引发混乱和不满。病患需要排队等候&#xff0c;挂号过程繁琐&#xff…

杨氏矩阵(有一个数字矩阵,矩阵的每行从左到右的递增的,矩阵从上到下是递增的请编写一个程序,在这样的矩阵中查找某个数字是否存在)

//杨氏矩阵 //有一个数字矩阵&#xff0c;矩阵的每行从左到右的递增的&#xff0c;矩阵从上到下是递增的 //请编写一个程序&#xff0c;在这样的矩阵中查找某个数字是否存在 // 1 2 3 // 4 5 6 // 7 8 9 #include<stdio.h> int main() {int a[3][3] { 0 };int i 0, j …

【设计一个恒流转恒压用于电池充电管理】2022-01-25

设计一个恒流转恒压用于电池充电管理&#xff0c;恒流定时恒压&#xff0c;看到一个限流稳压电路图。以下参数进行设计限流恒流<5安培稳压恒压12.6伏特&#xff0c;功率管选型NMOS场效应管IRF7403&#xff08;AO4407A&#xff09;&#xff0c;输入电压与输出压差必须大于4.4…

【计算机网络】HTTP报文详解,HTTPS基于HTTP做了哪些改进?(面试经典题)

HTTP协议基本报文格式 在计算机网络中&#xff0c;HTTP&#xff08;超文本传输协议&#xff09;是应用层的一种协议&#xff0c;用于客户端&#xff08;通常是浏览器&#xff09;和服务器之间的通信。HTTP报文分为请求报文和响应报文&#xff0c;以下是它们的基本格式。 1. H…

服务器数据恢复—服务器硬盘指示灯亮黄灯,raid崩溃的数据恢复案例

服务器数据恢复环境&#xff1a; 一台浪潮服务器中有一组由6块SAS硬盘组建的RAID。服务器上划分了1个卷&#xff0c;存放Oracle数据库文件。 服务器故障&检测&#xff1a; 服务器上有两个硬盘指示灯亮黄灯&#xff0c;RAID崩溃&#xff0c;服务器不可用。 将故障服务器中所…

【机器学习】图像识别——计算机视觉在工业自动化中的应用

1. 引言 随着人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;的快速发展&#xff0c;计算机视觉已成为工业自动化中的核心技术之一。图像识别&#xff0c;作为计算机视觉领域的重要分支&#xff0c;能够通过分析和理解图像或视频数据来识别、分类或检…

【LeetCode:349. 两个数组的交集 + 哈希表】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

如何使用 Browserless 抓取动态网站?

什么是动态网页&#xff1f; 动态网页是指其内容并非完全直接嵌入在静态HTML中&#xff0c;而是通过服务器端或客户端渲染生成的网页。 它可以根据用户的操作实时显示数据&#xff0c;例如在用户点击按钮或向下滚动页面时加载更多内容&#xff08;如无限滚动&#xff09;。这…

查缺补漏----三次握手与四次挥手

注意事项&#xff1a; ① 如果是和FTP服务器建立连接&#xff0c;那么要建立两个TCP连接。一个是控制连接一个是数据连接。 ② SYN报文段不能携带数据。三次握手的最后一个报文段可以捎带数据&#xff0c;但是如果不携带数据&#xff0c;那么就不消耗序号。 ③ 在断开连接过程中…