日期控件不許修改

編程,大家都希望越簡單越好,我也不例外。比如要輸入日期時,我會選擇簡單的CalendarTextBox 。 理由很簡單,總所周知判斷日期很麻煩,要考慮各種因素,但是使用CalendarTextBox 就使的一切都簡單化了,省去的大量判斷程式。 但隨之又出現了新的問題,CalendarTextBox 沒有readOnly屬性,因為一選,整個CalendarTextBox 就不可用了。就沒有辦法了嗎?當然不是。 因為下面就有解決的方法: 1.加入綫面代碼 AutoPostBack="false" ShowImage="False" onpaste="return false;" onkeypress="event.keyCode=0;event.returnValue=false;" onkeydown="this.select();" onclick="this.select();" style="ime-mode: disabled;" 2.使用正則表達式 http://topic.youkuaiyun.com/t/20030928/15/2311107.html
# ======================================== # 🚚 在途未入库管理窗口(防重复打开)—— 完整修复版 # ✅ 增加 "已入库" 列,并正确读取 ImportedQty # ======================================== in_transit_open = False def open_in_transit_window(): if not cursor: messagebox.showwarning("警告", "数据库未连接,无法管理在途数据") return global in_transit_open if in_transit_open: messagebox.showwarning("提示", "在途未入库窗口已打开。") return in_transit_open = True window = tk.Toplevel(root) window.title("在途未入库管理") window.geometry("1180x650") # --- 定义变量 --- item_var = tk.StringVar() qty_var = tk.StringVar() so_var_local = tk.StringVar() sn_var_local = tk.StringVar() remark_var = tk.StringVar() ship_date_var = tk.StringVar() search_var = tk.StringVar() # --- 创建 Treeview 表格 --- tree = ttk.Treeview( window, columns=("物料编号", "数量", "销售订单", "序列号", "备注", "发货日期", "已入库"), show="headings", height=22 ) headers = ["物料编号", "数量", "销售订单", "序列号", "备注", "发货日期", "已入库"] widths = [150, 80, 120, 180, 150, 120, 80] for header, width in zip(headers, widths): tree.heading(header, text=header) tree.column(header, width=width, anchor='center') tree.grid(row=8, column=0, columnspan=4, padx=10, pady=10, sticky="nsew") # ======================================== # ✅ 功能函数定义 # ======================================== def refresh_list(filter_text=""): """刷新表格数据,可带搜索过滤""" for row in tree.get_children(): tree.delete(row) try: if filter_text.strip(): like_filter = f"%{filter_text}%" query = """ SELECT Item, Qty, SO, SN, 备注, 发货日期, ImportedQty FROM [in_transit] WHERE Item LIKE ? OR Qty LIKE ? OR SO LIKE ? OR SN LIKE ? OR 备注 LIKE ? OR 发货日期 LIKE ? OR CAST(ImportedQty AS VARCHAR) LIKE ? """ params = (like_filter,) * 7 # 注意:现在是7个参数 cursor.execute(query, params) else: cursor.execute("SELECT Item, Qty, SO, SN, 备注, 发货日期, ImportedQty FROM [in_transit]") for row in cursor.fetchall(): values = [ str(row[0] or ""), # Item str(row[1]), # Qty str(row[2] or ""), # SO str(row[3] or ""), # SN str(row[4] or ""), # 备注 str(row[5] or ""), # 发货日期 str(row[6] or "0") # ImportedQty → 显示为“已入库” ] tree.insert("", tk.END, values=values) except Exception as e: messagebox.showerror("读取失败", f"无法加载在途数据:\n{e}") def add_record(): """添加新记录,默认 ImportedQty=0""" item = item_var.get().strip() qty = qty_var.get().strip() so = so_var_local.get().strip() sn = sn_var_local.get().strip() remark = remark_var.get().strip() ship_date = ship_date_var.get().strip() if not item or not qty: messagebox.showwarning("提示", "请至少输入【物料编号】和【数量】") return try: float(qty) except ValueError: messagebox.showwarning("提示", "数量必须是数字") return try: cursor.execute(""" INSERT INTO [in_transit] (Item, Qty, SO, SN, 备注, 发货日期, ImportedQty) VALUES (?, ?, ?, ?, ?, ?, ?) """, (item, qty, so, sn, remark, ship_date, 0)) # 初始化 ImportedQty 为 0 conn.commit() messagebox.showinfo("成功", "✅ 记录已添加") clear_inputs() refresh_list() except Exception as e: conn.rollback() messagebox.showerror("错误", f"添加失败:\n{e}") def delete_record(): """删除选中的记录""" selected = tree.selection() if not selected: messagebox.showwarning("提示", "请先选择要删除的记录") return item = tree.item(selected[0])['values'][0] sn = tree.item(selected[0])['values'][3] if messagebox.askyesno("确认删除", f"确定要删除该在途记录?\n物料编号:{item}\n序列号:{sn}"): try: cursor.execute("DELETE FROM [in_transit] WHERE Item = ? AND SN = ?", (item, sn)) conn.commit() messagebox.showinfo("成功", "🗑️ 记录已删除") refresh_list() except Exception as e: conn.rollback() messagebox.showerror("错误", f"删除失败:\n{e}") def on_double_click(event): """双击编辑记录""" selected = tree.selection() if not selected: return item_values = tree.item(selected[0])['values'] original_item, original_sn = item_values[0], item_values[3] edit_win = tk.Toplevel(window) edit_win.title("编辑在途记录") edit_win.geometry("500x420") v_item = tk.StringVar(value=item_values[0]) v_qty = tk.StringVar(value=item_values[1]) v_so = tk.StringVar(value=item_values[2]) v_sn = tk.StringVar(value=item_values[3]) v_remark = tk.StringVar(value=item_values[4]) v_ship_date = tk.StringVar(value=item_values[5]) fields = [ ("物料编号", v_item), ("数量", v_qty), ("销售订单", v_so), ("序列号", v_sn), ("备注", v_remark), ("发货日期", v_ship_date), ] for i, (label, var) in enumerate(fields): ttk.Label(edit_win, text=label).grid(row=i, column=0, padx=15, pady=6, sticky='e') ttk.Entry(edit_win, textvariable=var, width=30).grid(row=i, column=1, padx=15, pady=6, sticky='w') def save_edit(): new_item = v_item.get().strip() new_qty = v_qty.get().strip() new_so = v_so.get().strip() new_sn = v_sn.get().strip() new_remark = v_remark.get().strip() new_ship_date = v_ship_date.get().strip() if not new_item or not new_qty: messagebox.showwarning("提示", "物料编号和数量不能为空") return try: float(new_qty) except ValueError: messagebox.showwarning("提示", "数量必须是有效数字") return try: cursor.execute(""" UPDATE [in_transit] SET Item = ?, Qty = ?, SO = ?, SN = ?, 备注 = ?, 发货日期 = ? WHERE Item = ? AND SN = ? """, (new_item, new_qty, new_so, new_sn, new_remark, new_ship_date, original_item, original_sn)) conn.commit() messagebox.showinfo("成功", "💾 修改已保存") edit_win.destroy() refresh_list() window.lift() except Exception as e: conn.rollback() messagebox.showerror("错误", f"更新失败:\n{e}") ttk.Button(edit_win, text="保存修改", command=save_edit).grid(row=len(fields), column=0, columnspan=2, pady=20) def clear_inputs(): """清空输入框""" item_var.set("") qty_var.set("") so_var_local.set("") sn_var_local.set("") remark_var.set("") ship_date_var.set("") def copy_selected(): """复制选中行内容到剪贴板""" selected = tree.selection() if selected: values = tree.item(selected[0])['values'] text = '\t'.join(str(v) for v in values) window.clipboard_clear() window.clipboard_append(text) def show_context_menu(event): """右键弹出菜单""" if tree.identify_row(event.y): tree.selection_set(tree.identify_row(event.y)) context_menu.post(event.x_root, event.y_root) def import_from_excel(): """从 Excel 导入并覆盖所有在途数据""" filepath = filedialog.askopenfilename( title="选择在途数据Excel文件", filetypes=[("Excel 文件", "*.xlsx"), ("所有文件", "*.*")] ) if not filepath: return if not messagebox.askyesno("⚠️ 确认操作", "此操作将清空当前所有在途数据,\n并用Excel中的数据完全替换。\n\n是否继续?"): return try: df = pd.read_excel(filepath) required_columns = {'Item', 'Qty', 'SO', 'SN', '备注', '发货日期'} missing = required_columns - set(df.columns) if missing: messagebox.showerror("格式错误", f"❌ 缺少必要列:{missing}\n请确保包含以下列:\n{required_columns}") return df['Item'] = df['Item'].astype(str).str.strip() df['Qty'] = pd.to_numeric(df['Qty'], errors='coerce').fillna(0) df['SO'] = df['SO'].astype(str).str.strip() df['SN'] = df['SN'].astype(str).str.strip() df['备注'] = df['备注'].astype(str).str.strip() df['发货日期'] = df['发货日期'].astype(str).str.strip() valid_df = df.dropna(subset=['Item']).query('Item != "nan" and Item != ""') if valid_df.empty: messagebox.showwarning("无有效数据", "Excel 中没有可导入的有效数据行。") return cursor.execute("DELETE FROM [in_transit]") inserted_count = 0 for _, row in valid_df.iterrows(): cursor.execute(""" INSERT INTO [in_transit] (Item, Qty, SO, SN, 备注, 发货日期, ImportedQty) VALUES (?, ?, ?, ?, ?, ?, ?) """, (row['Item'], row['Qty'], row['SO'], row['SN'], row['备注'], row['发货日期'], 0)) inserted_count += 1 conn.commit() messagebox.showinfo("导入成功", f"✅ 已成功导入 {inserted_count} 条在途记录!") refresh_list() except Exception as e: conn.rollback() messagebox.showerror("导入失败", f"发生错误:\n{str(e)}") 在途管理窗口中 手动创建的日期 改成自动填写当前日期 且不可在页面中编辑
最新发布
09-26
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值