2201_75335496 2024-06-28 17:07 采纳率: 83.8%
浏览 2
已结题

python tkinter某个地方使用线程之后,程序异常报错malformed bucket chain in Tcl_DeleteHashEntry并被暂停,之后直接退出,怎么解决?

python tkinter某个地方使用线程之后,程序异常报错并被暂停,之后直接退出,怎么解决?
报错内容:

malformed bucket chain in Tcl_DeleteHashEntry

代码:

import tkinter as tk
from tkinter import ttk
import ctypes
import struct
import sys
import os
import time
import psutil
from functools import partial
from cutool import systemTool
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.ticker import MultipleLocator
from threading import Thread as td
#获取任务栏高度
def get_taskbar_height():
    user32 = ctypes.windll.user32
    SPI_GETWORKAREA = 48
    rect = ctypes.create_string_buffer(16)
    user32.SystemParametersInfoA(SPI_GETWORKAREA, 0, rect, 0)
    _, _, _, bottom = struct.unpack("4i", rect.raw)
    screen_height = user32.GetSystemMetrics(1)
    taskbar_height = screen_height - bottom
    return taskbar_height
# ------------------------------功能实现-info显示------------------------------ #
def showInfoFrame():
    cpus = psutil.cpu_percent()
    mems = systemTool.GetMemInfo()["memRealUsed"] / systemTool.GetMemInfo()["memTotal"] * 100
    dsks = systemTool.GetIoReadWrite()
    dsks = (dsks["read"] + dsks["write"]) / 1024 / 1024
    nets = systemTool.GetNetWork()
    nets = (nets["up"] + nets["down"]) / 1024
    cpuInfo.config(text = f"CPU: %.2f" % cpus + "%")
    memInfo.config(text = "内存: %.2f" % mems + "%")
    dskInfo.config(text = "硬盘: %.2fMB" % dsks)
    netInfo.config(text = "网络: %.2fMB" % nets)
    pidInfo.config(text = f"进程: {len(psutil.pids())}")
    #win.after(0,valueGet,cpus,mems,dsks,nets)
    td(target = valueGet,args = (cpus,mems,dsks,nets),daemon = True).start()
    td(target = getPid).start()
    #getPid()
    win.update()
    time.sleep(updateInterval / 1000)
    td(target = showInfoFrame).start()
    #win.after(updateInterval,showInfoFrame)
# ------------------------------功能实现-进程获取------------------------------ #
'''def getPid():
    pidlist = []
    pl = [[o,*pidtree.item(o)["values"]] for o in pidtree.get_children()]
    for i in psutil.pids():
        if pl == []:
            pidlist.append((psutil.Process(i).name(),i))
        for o in pl:
            #print(f"pidi:{i},pido:{o}")
            if not i != o[1:]:
                pidtree.delete(o[0])
                pidlist.append((psutil.Process(i).name(),i))
    pidlist.sort()
    for i in pidlist:
        pidtree.insert("",tk.END,value = i)'''
def getPid():
    def tditem(a,v):
        def itm():
            pidtree.item(a,values = v)
        td(target = itm).start()
    def tdinsert(a,b,v):
        def ist():pidtree.insert(a,b,values = v)
        td(target = ist).start()
    tree = pidtree
    for process in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_info', 'io_counters', 'num_threads']):
            try:
                pid = process.info['pid']
                name = process.info['name']
                cpu_percent = process.info['cpu_percent']
                memory_info = process.info['memory_info'].rss / (1024 * 1024)
                io_counters = process.info['io_counters']
                threads = process.info['num_threads']

                # Check if the process is already in the treeview
                item = tree.get_children()
                found = False
                for i in item:
                    if tree.item(i)["values"][0] == pid:
                        found = True
                        #print("item:",i,pid)
                        if tree.item(i)["values"] != (pid, name, cpu_percent, memory_info, io_counters.read_bytes + io_counters.write_bytes, threads):
                            tditem(i,v = [pid, name, cpu_percent, memory_info, io_counters.read_bytes + io_counters.write_bytes, threads])
                        break

                if not found:
                    tdinsert("", "end",v=[pid, name, cpu_percent, memory_info, io_counters.read_bytes + io_counters.write_bytes, threads])
                    #print("insert:",pid)
            except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
                pass
            
# ------------------------------功能实现-参数监视------------------------------ #
def valueGet(cpu,mem,dsk,net):
    #cpu
    cpuPlot.append(cpu)
    cpuPlot.pop(0)
    cpuAx.clear()
    cpuAx.plot(cpuPlot, color="lightgreen")
    cpuAx.set_yticks([0,100])
    cpuAx.grid(zorder=0, linewidth="0.0", linestyle="-", color=(0,0,0))
    cpuCanvas.draw()
    #mem
    memPlot.append(mem)
    memPlot.pop(0)
    memAx.clear()
    memAx.plot(memPlot, color="b")
    memAx.set_yticks([0,100])
    memAx.grid(zorder=0, linewidth="0.0", linestyle="-", color=(0,0,0))
    memCanvas.draw()
    #dsk
    dskPlot.append(dsk)
    dskPlot.pop(0)
    dskAx.clear()
    dskAx.plot(dskPlot, color="cyan")
    dskAx.set_yticks([0,20])
    dskAx.grid(zorder=0, linewidth="0.0", linestyle="-", color=(0,0,0))
    dskCanvas.draw()
    #net
    netPlot.append(net)
    netPlot.pop(0)
    netAx.clear()
    netAx.plot(netPlot, color="orange")
    netAx.set_yticks([0,20])
    netAx.grid(zorder=0, linewidth="0.0", linestyle="-", color=(0,0,0))
    netCanvas.draw()
    print(cpu,mem,dsk,net)

win = tk.Tk()
win.title("任务管理器")
winsize = (800,600)
scrsize = (win.winfo_screenwidth(),win.winfo_screenheight())
win.geometry("{}x{}+{}+{}".format(*winsize,(scrsize[0] - winsize[0]) // 2,(scrsize[1] - winsize[1] - get_taskbar_height()) // 2))
win.minsize(780,100)
#告诉操作系统使用程序自身的dpi适配
ctypes.windll.shcore.SetProcessDpiAwareness(1)
#获取屏幕的缩放因子
ScaleFactor=ctypes.windll.shcore.GetScaleFactorForDevice(0)
#设置程序缩放
win.tk.call('tk', 'scaling', ScaleFactor/75)
#------------------------------窗口主菜单------------------------------#
updateInterval = 500 # ms,min:200,max:2000

def menuDraw():
    def setColorViewm():
        cwin = tk.Toplevel(win)
        cwin.geometry("600x400")
        cwin.resizable(0,0)
        cwin.title("任务管理器-设置颜色")
    #主菜单
    wmenu = tk.Menu(win)
    win.config(menu = wmenu)
    #副菜单
    filem = tk.Menu(wmenu,tearoff = 0) # 文件
    #monim = tk.Menu(wmenu,tearoff = 0) # 监视器
    optim = tk.Menu(wmenu,tearoff = 0) # 选项
    viewm = tk.Menu(wmenu,tearoff = 0) # 视图
    searm = tk.Menu(wmenu,tearoff = 0) # 搜索
    helpm = tk.Menu(wmenu,tearoff = 0) # 帮助
    #绑定副菜单
    wmenu.add_cascade(label = "文件",menu = filem)
    wmenu.add_cascade(label = "选项",menu = optim)
    wmenu.add_cascade(label = "搜索",menu = searm)
    wmenu.add_cascade(label = "帮助",menu = helpm)
    
    #文件-副菜单
    filem.add_command(label = "导出进程列表")
    filem.add_separator()
    filem.add_command(label = "退出")
    
    #选项-副菜单
    optim.add_checkbutton(label = "随系统启动")
    optim.add_checkbutton(label = "只允许一个实例启动")
    optim.add_separator()
    optim.add_checkbutton(label = "窗口置顶")
    optim.add_checkbutton(label = "通知栏图标显示")
    optim.add_checkbutton(label = "最小化时隐藏")
    optim.add_separator()
    optim.add_checkbutton(label = "结束进程时确认操作")
    optim.add_checkbutton(label = "创建进程时确认操作")
    optim.add_cascade(label = "刷新速度")
    
    #搜索-父菜单
    #帮助-父菜单

menuDraw()
#窗口下部信息显示栏
infoFrame = tk.Frame(win,relief = "solid",bd = 1) # flat, groove, raised, ridge, solid, or sunken
cpuInfo = tk.Label(infoFrame,text = "CPU: -%")
memInfo = tk.Label(infoFrame,text = "内存: -%")
dskInfo = tk.Label(infoFrame,text = "硬盘: -KB")
netInfo = tk.Label(infoFrame,text = "网络: -KB")
pidInfo = tk.Label(infoFrame,text = "进程: -")
sizeGrip = ttk.Sizegrip(infoFrame)

cpuInfo.grid(row = 0,column = 0,sticky = "w")
ttk.Separator(infoFrame,orient = tk.VERTICAL).grid(row = 0,column = 1,sticky = "ns")
memInfo.grid(row = 0,column = 2,sticky = "w")
ttk.Separator(infoFrame,orient = tk.VERTICAL).grid(row = 0,column = 3,sticky = "ns")
dskInfo.grid(row = 0,column = 4,sticky = "w")
ttk.Separator(infoFrame,orient = tk.VERTICAL).grid(row = 0,column = 5,sticky = "ns")
pidInfo.grid(row = 0,column = 6,sticky = "w")
ttk.Separator(infoFrame,orient = tk.VERTICAL).grid(row = 0,column = 7,sticky = "ns")
netInfo.grid(row = 0,column = 8,sticky = "w")
ttk.Separator(infoFrame,orient = tk.VERTICAL).grid(row = 0,column = 9,sticky = "ns")
sizeGrip.grid(row = 0,column = 10,sticky = "se")


infoFrame.grid(row = 1,column = 0,sticky = "we")
infoFrame.columnconfigure(0,minsize = 120)
infoFrame.columnconfigure(2,minsize = 120)
infoFrame.columnconfigure(4,minsize = 120)
infoFrame.columnconfigure(6,minsize = 100)
infoFrame.columnconfigure(8,minsize = 120)
infoFrame.columnconfigure(10,weight = 1)

win.rowconfigure(0,weight = 1)
win.columnconfigure(0,weight = 1)

# ------------------------------窗口主要控件------------------------------ #
notebook = ttk.Notebook(win)
#进程列表
pidtreeFrame = tk.Frame(notebook)
pidtree = ttk.Treeview(pidtreeFrame,show = "headings",columns = list(range(7)))
titlenamelist = ['名称','PID','CPU使用率(%)','内存(MB)','磁盘读(KB)','磁盘写(KB)','线程数']
titlewidthlist = [100,50,80,100,80,80,50]
titleanchorlist = ["w","e","e","e","e","e","e"]
for i in range(7):
    pidtree.column(i,anchor = tk.CENTER,width = titlewidthlist[i])
    pidtree.heading(i,text = titlenamelist[i],anchor = titleanchorlist[i])

pidtreeScrollx = ttk.Scrollbar(pidtreeFrame,orient = tk.HORIZONTAL,command = pidtree.xview)
pidtreeScrolly = ttk.Scrollbar(pidtreeFrame,orient = tk.VERTICAL,command = pidtree.yview)
pidtreeScrollTab = tk.Frame(pidtreeFrame) # 填充右下角的空白
pidtree.configure(xscrollcommand = pidtreeScrollx.set)
pidtree.configure(yscrollcommand = pidtreeScrolly.set)
pidtreeScrollTab.grid(row = 1,column = 1,sticky = "nsew")
pidtreeScrollx.grid(row = 1,column = 0,sticky = "nsew")
pidtreeScrolly.grid(row = 0,column = 1,sticky = "nsew")
pidtreeFrame.rowconfigure(0,weight = 1)
pidtreeFrame.columnconfigure(0,weight = 1)
pidtree.grid(row = 0,column = 0,sticky = "nsew")
pidtreeFrame.grid(row = 0,column = 0,sticky = "nsew")




notebook.add(pidtreeFrame,text = "进程列表" + " " * 4)

#参数监视
historyListLen = 100
canvasSize = (200,160)
valueFrame = tk.Frame(notebook)
pandFrame = tk.PanedWindow(valueFrame,orient = tk.HORIZONTAL)
pandcmdn = tk.PanedWindow(pandFrame,orient = tk.VERTICAL)
pandcm = tk.PanedWindow(pandcmdn,orient = tk.HORIZONTAL)
panddn = tk.PanedWindow(pandcmdn,orient = tk.HORIZONTAL)

vif = tk.Frame(pandFrame)
cpuf = ttk.Labelframe(vif,text = "CPU")
memf = ttk.Labelframe(vif,text = "内存")
dskf = ttk.Labelframe(vif,text = "硬盘")
netf = ttk.Labelframe(vif,text = "网络")
class Vif:
    class Cpuf:
        cpus = systemTool.GetCpuInfo()
        cpuName = cpus["cpu_name"]
        cpuCount = cpus["cpu_count"]
        cpuThreads = cpus["cpu_threads"]
        cpuCore = cpus["cpu_core"]
        
        cpuNamel = tk.Label(cpuf,text = "名称:")
        cpuCountl = tk.Label(cpuf,text = "物理个数:")
        cpuThreadsl = tk.Label(cpuf,text = "逻辑核心数:")
        cpuCorel = tk.Label(cpuf,text = "物理核心数:")
        
        cpuNamev = tk.Label(cpuf,text = cpuName)
        cpuCountv = tk.Label(cpuf,text = cpuCount)
        cpuThreadsv = tk.Label(cpuf,text = cpuThreads)
        cpuCorev = tk.Label(cpuf,text = cpuCore)
        
        cpuNamel.grid(row = 0,column = 0,sticky = "w")
        cpuCountl.grid(row = 1,column = 0,sticky = "w")
        cpuThreadsl.grid(row = 2,column = 0,sticky = "w")
        cpuCorel.grid(row = 3,column = 0,sticky = "w")
        
        cpuNamev.grid(row = 0,column = 1,sticky = "e")
        cpuCountv.grid(row = 1,column = 1,sticky = "e")
        cpuThreadsv.grid(row = 2,column = 1,sticky = "e")
        cpuCorev.grid(row = 3,column = 1,sticky = "e")
    class Memf:
        mems = systemTool.GetMemInfo()
        memTotal = mems["memTotal"]
        memTotall = tk.Label(memf,text = "内存总数(MB)")
        memTotalv = tk.Label(memf,text = memTotal)
        
        memTotall.grid(row = 0,column = 0,sticky = "w")
        memTotalv.grid(row = 0,column = 1,sticky = "e")
    class Dskf:
        dsks = systemTool.GetDiskInfo()
        dsklf = tk.Frame(dskf,height = 50)
        tree = ttk.Treeview(dsklf,show = "headings",columns = list(range(5)))
        titlenamelist = ["盘符","总大小(GB)","已用空间(GB)","可用空间(GB)","格式"]
        titlewidthlist = [50,100,100,100,70]
        titleanchorlist = ["w","e","e","e","w"]
        for i in range(5):
            tree.column(i,anchor = tk.CENTER,width = titlewidthlist[i])
            tree.heading(i,text = titlenamelist[i],anchor = titleanchorlist[i])
        treeScrollx = ttk.Scrollbar(dsklf,orient = tk.HORIZONTAL,command = tree.xview)
        treeScrolly = ttk.Scrollbar(dsklf,orient = tk.VERTICAL,command = tree.yview)
        treeScrollTab = tk.Frame(dsklf) # 填充右下角的空白
        tree.configure(xscrollcommand = treeScrollx.set)
        tree.configure(yscrollcommand = treeScrolly.set)
        treeScrollTab.grid(row = 1,column = 1,sticky = "nsew")
        treeScrollx.grid(row = 1,column = 0,sticky = "nsew")
        treeScrolly.grid(row = 0,column = 1,sticky = "nsew")
        dsklf.rowconfigure(0,weight = 1)
        dsklf.columnconfigure(0,weight = 1)
        tree.grid(row = 0,column = 0,sticky = "nsew")
        for i in dsks:
            dskpath = i["path"]
            dsktotal = "%.2f" % (i["size"]["total"] / 1073741824)
            dskused = "%.2f" % (i["size"]["used"] / 1073741824)
            dskfree = "%.2f" % (i["size"]["free"] / 1073741824)
            dskfstype = i["fstype"]
            tree.insert("",tk.END,values = (dskpath,dsktotal,dskused,dskfree,dskfstype))
        dsklf.grid(row = 0,column = 0)

cpuf.grid(row = 0,column = 0,sticky = "nswe")
memf.grid(row = 1,column = 0,sticky = "nswe")
dskf.grid(row = 2,column = 0,sticky = "nswe")
netf.grid(row = 3,column = 0,sticky = "nswe")

pandcm.grid(row = 0,column = 0,sticky = "nsew")
panddn.grid(row = 1,column = 0,sticky = "nsew")
pandcmdn.grid(row = 0,column = 0,sticky = "nsew")
pandFrame.grid(row = 0,column = 0,sticky = "nsew")
valueFrame.rowconfigure(0,weight = 1)
valueFrame.columnconfigure(0,weight = 1)
#cpu
cpupFrame = tk.Frame(pandcm,bd = 1,relief = "sunken")
mempFrame = tk.Frame(pandcm,bd = 1,relief = "sunken")
dskpFrame = tk.Frame(panddn,bd = 1,relief = "sunken")
netpFrame = tk.Frame(panddn,bd = 1,relief = "sunken")

cpupFrame.rowconfigure(1,weight = 1)
mempFrame.rowconfigure(1,weight = 1)
dskpFrame.rowconfigure(1,weight = 1)
netpFrame.rowconfigure(1,weight = 1)
cpupFrame.columnconfigure(0,weight = 1)
mempFrame.columnconfigure(0,weight = 1)
dskpFrame.columnconfigure(0,weight = 1)
netpFrame.columnconfigure(0,weight = 1)
win.update()

tk.Label(cpupFrame,text = "CPU(%)").grid(row = 0,column = 0,sticky = "w",padx = 10,pady = 5)
tk.Label(mempFrame,text = "内存(%)").grid(row = 0,column = 0,sticky = "w",padx = 10,pady = 5)
tk.Label(dskpFrame,text = "硬盘(MB)").grid(row = 0,column = 0,sticky = "w",padx = 10,pady = 5)
tk.Label(netpFrame,text = "网络(MB)").grid(row = 0,column = 0,sticky = "w",padx = 10,pady = 5)
cpuFig,cpuAx = plt.subplots()
memFig,memAx = plt.subplots()
dskFig,dskAx = plt.subplots()
netFig,netAx = plt.subplots()
cpuCanvas = FigureCanvasTkAgg(cpuFig,master = cpupFrame)
memCanvas = FigureCanvasTkAgg(memFig,master = mempFrame)
dskCanvas = FigureCanvasTkAgg(dskFig,master = dskpFrame)
netCanvas = FigureCanvasTkAgg(netFig,master = netpFrame)
cpuCanvas.get_tk_widget().grid(row = 1,column = 0,padx = 10,pady = 5)
memCanvas.get_tk_widget().grid(row = 1,column = 0,padx = 10,pady = 5)
dskCanvas.get_tk_widget().grid(row = 1,column = 0,padx = 10,pady = 5)
netCanvas.get_tk_widget().grid(row = 1,column = 0,padx = 10,pady = 5)
cpuFig.set_facecolor((0,0,0))
memFig.set_facecolor((0,0,0))
dskFig.set_facecolor((0,0,0))
netFig.set_facecolor((0,0,0))
cpuAx.set_facecolor((0,0,0))
memAx.set_facecolor((0,0,0))
dskAx.set_facecolor((0,0,0))
netAx.set_facecolor((0,0,0))
cpuAx.tick_params(axis="x", labelcolor="black")
memAx.tick_params(axis="x", labelcolor="black")
dskAx.tick_params(axis="x", labelcolor="black")
netAx.tick_params(axis="x", labelcolor="black")
cpuAx.tick_params(axis="y", labelcolor="black")
memAx.tick_params(axis="y", labelcolor="black")
dskAx.tick_params(axis="y", labelcolor="black")
netAx.tick_params(axis="y", labelcolor="black")
cpuAx.yaxis.set_major_locator(MultipleLocator(10))
memAx.yaxis.set_major_locator(MultipleLocator(10))
dskAx.yaxis.set_major_locator(MultipleLocator(10))
netAx.yaxis.set_major_locator(MultipleLocator(10))
cpuCanvas.get_tk_widget()#.config(width = canvasSize[0], height = canvasSize[1])
memCanvas.get_tk_widget()#.config(width = canvasSize[0], height = canvasSize[1])
dskCanvas.get_tk_widget()#.config(width = canvasSize[0], height = canvasSize[1])
netCanvas.get_tk_widget()#.config(width = canvasSize[0], height = canvasSize[1])
cpuPlot = [0 for _ in range(historyListLen)]
memPlot = [0 for _ in range(historyListLen)]
dskPlot = [0 for _ in range(historyListLen)]
netPlot = [0 for _ in range(historyListLen)]

cpupFrame.grid(row = 0,column = 0,sticky = "nsew",padx = 1,pady = 1)
mempFrame.grid(row = 0,column = 0,sticky = "nsew",padx = 1,pady = 1)
dskpFrame.grid(row = 0,column = 0,sticky = "nsew",padx = 1,pady = 1)
netpFrame.grid(row = 0,column = 0,sticky = "nsew",padx = 1,pady = 1)

pandcm.add(cpupFrame,width = 280)
pandcm.add(mempFrame,width = 280)
panddn.add(dskpFrame,width = 280)
panddn.add(netpFrame,width = 280)
pandcmdn.add(pandcm,height = 270)
pandcmdn.add(panddn,height = 270)
pandFrame.add(pandcmdn)
pandFrame.add(vif)
notebook.add(valueFrame,text = "参数监视" + " " * 4)
notebook.grid(row = 0,column = 0,sticky = "nsew")
win.update()
getPid()
showInfoFrame()
win.mainloop()

第44行当使用win.after时,虽然卡顿但不报错;使用线程启动时,前面还流畅,但操作了不到一秒就卡死被暂停,1秒之后直接崩溃

  • 写回答

1条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-06-28 17:07
    关注

    引自免费微信小程序:皆我百晓生

    这个问题可能源于Python的Tkinter库和线程之间的交互问题。Tkinter库不是线程安全的,这意味着在多个线程中同时操作Tkinter窗口可能会导致未定义的行为,包括崩溃和挂起。

    在你的代码中,你使用了Thread来执行showInfoFramegetPid函数,这两个函数都试图更新Tkinter窗口。这可能导致线程安全问题。

    一个可能的解决方案是,使用Tkinter的after方法来安排更新,而不是使用线程。after方法会确保更新在Tkinter的主线程中执行,这是安全的。

    例如,你可以将showInfoFramegetPid函数中的win.update()替换为win.after(updateInterval, showInfoFrame),这样它们就会在主线程中按照指定的时间间隔执行。

    另外,对于getPid函数,你可能需要修改它以在主线程中更新pidtree,而不是在子线程中。你可以使用win.after来安排更新,或者将需要更新的数据传递给主线程,然后在主线程中更新。

    这是一个修改后的getPid函数示例:

    def getPid():
        def tditem(a,v):
            def itm():
                pidtree.item(a,values = v)
                win.after(0, getPid)  # Schedule another call to getPid
            win.after(0, itm)  # Arrange for the update to happen in the main thread
    
        # ... (rest of the function)
    
        for process in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_info', 'io_counters', 'num_threads']):
            # ... (rest of the loop)
    
            # Schedule an update to the main thread
            win.after(0, tditem, i, [pid, name, cpu_percent, memory_info, io_counters.read_bytes + io_counters.write_bytes, threads])
    

    在这个修改后的版本中,tditem函数被安排在主线程中执行,而不是在子线程中。每次更新pidtree时,都会安排下一次调用getPid,这样更新就会在主线程中连续进行。

    注意,这个解决方案假设你的目标是在主线程中更新Tkinter窗口,而不是在子线程中。如果你的目标是在子线程中执行某些操作,并且不需要更新Tkinter窗口,那么你可能需要采取不同的策略来处理子线程的结果。

    希望这个解答能帮助你解决问题!如果还有其他问题,请随时提问。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 6月28日
  • 创建了问题 6月28日

悬赏问题

  • ¥15 ansys fluent计算闪退
  • ¥15 有关wireshark抓包的问题
  • ¥15 需要写计算过程,不要写代码,求解答,数据都在图上
  • ¥15 向数据表用newid方式插入GUID问题
  • ¥15 multisim电路设计
  • ¥20 用keil,写代码解决两个问题,用库函数
  • ¥50 ID中开关量采样信号通道、以及程序流程的设计
  • ¥15 U-Mamba/nnunetv2固定随机数种子
  • ¥15 vba使用jmail发送邮件正文里面怎么加图片
  • ¥15 vb6.0如何向数据库中添加自动生成的字段数据。