{"id":72,"date":"2025-11-30T12:22:00","date_gmt":"2025-11-30T04:22:00","guid":{"rendered":"https:\/\/ky1n.cn\/?p=72"},"modified":"2025-11-30T12:41:14","modified_gmt":"2025-11-30T04:41:14","slug":"%e6%8a%bd%e4%ba%ba%e8%bd%af%e4%bb%b6v3","status":"publish","type":"post","link":"https:\/\/ky1n.cn\/index.php\/2025\/11\/30\/%e6%8a%bd%e4%ba%ba%e8%bd%af%e4%bb%b6v3\/","title":{"rendered":"\u62bd\u4eba\u8f6f\u4ef6v3"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">\u57fa\u4e8ePython 3 Tkinter\u5f00\u53d1\u7684\u4e00\u6b3e\u591a\u540d\u5355\u52a0\u5bc6\u62bd\u4eba\u8f6f\u4ef6\u2014\u2014\u81ea\u52a8\u62bd\u4ebav3.0\u7248 base\u52a0\u5bc6v1.0\u7248<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u4e0b\u8f7d\u94fe\u63a5\uff1a<a href=\"https:\/\/wwbri.lanzoub.com\/iHeOS3ci0n4b\">\u84dd\u594f\u4e91 \u514d\u767b\u5f55 \u4e0d\u9650\u901f  \u5bc6\u7801:e4vc<\/a><\/p>\n\n\n\n<p class=\"has-large-font-size wp-block-paragraph\">\u4f7f\u7528\u63d0\u793a\uff1a<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1.\u8bf7\u89e3\u538b\u4f7f\u7528 \u53cc\u51fb\u8fd0\u884cexe<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">2.\u76ee\u5f55\u4e2dnameinfo\u6587\u4ef6\u5939\u91cc\u9762\u5b58\u653e\u7684\u662f\u540d\u5355\u52a0\u5bc6\u6587\u4ef6\uff0c\u5220\u9664\u540e\u8fd0\u884c\u8f6f\u4ef6\u81ea\u52a8\u751f\u6210\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">3.\u76ee\u5f55\u4e2d_internal\u6587\u4ef6\u5939\u91cc\u9762\u5b58\u653e\u7684\u662f\u52a0\u5bc6\u8fd0\u884c\u5e93\uff0c\u5220\u9664\u540e\u7a0b\u5e8f\u65e0\u6cd5\u6b63\u5e38\u8fd0\u884c\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">4.\u52a0\u5bc6\u540d\u5355\u6587\u4ef6\u4e00\u65e6\u88ab\u7be1\u6539\uff0c\u81ea\u52a8\u91cd\u7f6e\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>##\u516c\u793a\u6e90\u4ee3\u7801\uff1a\nimport tkinter as tk\nfrom tkinter import ttk, messagebox\nimport random\nimport os\nimport time\nimport base64\nimport shutil\n\n##Ky1n\u7f16\u5199  Written By Ky1n\n##BASE64\u52a0\u5bc6\u90e8\u5206\u7531Deepseek-R1\u8f85\u52a9\u7f16\u5199  The BASE64 Auxiliary Preparation By DeepSeek-R1 Large Model\n##\u6ce8\u91ca\u7531AI\u751f\u6210  AI-Generated Code Comments\n##\u53d8\u91cf\u540d\u7531AI\u89c4\u8303  AI-Standardized Variable Names\n##Windows\u53ef\u6267\u884c\u7a0b\u5e8f\u7531py-to-exe\u6253\u5305  Windows EXE Via py-to-exe\n\nclass RandomPickerApp:\n    def __init__(self, root):\n        self.root = root\n        self.root.title(\"\u62bd\u4ebav3 \u62d6\u6b64\u5904\u53ef\u79fb\u52a8\")\n        \n        # \u8bbe\u7f6e\u4e3b\u754c\u9762\u5927\u5c0f\u4e3a300x200\n        self.root.geometry(\"300x200\")\n        self.root.minsize(300, 200)\n        \n        # \u521d\u59cb\u5316\u540d\u5355\n        self.lists = {}\n        self.current_list = None\n        self.topmost = False\n        self.hidden = False\n        \n        # \u786e\u4fddnameinfo\u76ee\u5f55\u5b58\u5728\n        if not os.path.exists(\"nameinfo\"):\n            os.makedirs(\"nameinfo\")\n        \n        # \u521b\u5efa\u4e3b\u754c\u9762\n        self.create_main_interface()\n        \n        # \u52a0\u8f7d\u540d\u5355\n        if not self.load_lists():\n            # \u5982\u679c\u52a0\u8f7d\u5931\u8d25\uff0c\u663e\u793a\u9519\u8bef\u7a97\u53e3\n            self.show_decryption_error_dialog()\n        \n        # \u7f6e\u9876\u6309\u94ae\u72b6\u6001\n        self.update_top_button()\n        \n        # \u4f7f\u7a97\u53e3\u53ef\u62d6\u52a8\n        self.root.bind(\"&lt;ButtonPress-1>\", self.start_move)\n        self.root.bind(\"&lt;B1-Motion>\", self.do_move)\n    \n    def create_main_interface(self):\n        # \u4e3b\u6846\u67b6\n        main_frame = ttk.Frame(self.root)\n        main_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)\n        \n        # \u7ed3\u679c\u663e\u793a - \u4f7f\u7528\u66f4\u5927\u7684\u7a7a\u95f4\n        result_frame = ttk.Frame(main_frame)\n        result_frame.pack(fill=tk.BOTH, expand=True)\n        \n        self.result_label = ttk.Label(\n            result_frame, \n            text=\"\u8bf7\u9009\u62e9\u540d\u5355\", \n            font=(\"Arial\", 32, \"bold\"),\n            foreground=\"blue\",\n            anchor=tk.CENTER,\n            justify=tk.CENTER\n        )\n        self.result_label.pack(fill=tk.BOTH, expand=True)\n        \n        # \u5e95\u90e8\u63a7\u5236\u533a\u57df\n        control_frame = ttk.Frame(main_frame)\n        control_frame.pack(fill=tk.X, pady=(5, 0))\n        \n        # \u540d\u5355\u9009\u62e9\u653e\u5728\u5e95\u90e8\n        list_frame = ttk.Frame(control_frame)\n        list_frame.pack(fill=tk.X, pady=2)\n        \n        self.list_var = tk.StringVar()\n        self.list_combobox = ttk.Combobox(list_frame, textvariable=self.list_var, state=\"readonly\", width=15)\n        self.list_combobox.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=2)\n        self.list_combobox.bind(\"&lt;&lt;ComboboxSelected>>\", self.on_list_selected)\n        \n        # \u6309\u94ae\u533a\u57df\n        button_frame = ttk.Frame(control_frame)\n        button_frame.pack(fill=tk.X, pady=2)\n        \n        # \u4f7f\u7528\u7f51\u683c\u5e03\u5c40\u6309\u94ae\n        self.pick_button = ttk.Button(\n            button_frame, \n            text=\"\u62bd\u53d6\", \n            command=self.pick_random,\n            width=6\n        )\n        self.pick_button.grid(row=0, column=0, padx=2)\n        \n        self.top_button = ttk.Button(\n            button_frame, \n            text=\"\u7f6e\u9876\", \n            command=self.toggle_topmost,\n            width=6\n        )\n        self.top_button.grid(row=0, column=1, padx=2)\n        \n        edit_button = ttk.Button(\n            button_frame, \n            text=\"\u7f16\u8f91\", \n            command=self.open_edit_window,\n            width=6\n        )\n        edit_button.grid(row=0, column=2, padx=2)\n        \n        # \u9690\u85cf\u6309\u94ae\n        hide_button = ttk.Button(\n            button_frame, \n            text=\"\u9690\u85cf\", \n            command=self.hide_window,\n            width=6\n        )\n        hide_button.grid(row=0, column=3, padx=2)\n        \n        # \u914d\u7f6e\u6309\u94ae\u6846\u67b6\u7684\u5217\u6743\u91cd\n        button_frame.columnconfigure(0, weight=1)\n        button_frame.columnconfigure(1, weight=1)\n        button_frame.columnconfigure(2, weight=1)\n        button_frame.columnconfigure(3, weight=1)\n    \n    def start_move(self, event):\n        # \u5141\u8bb8\u5728\u7a97\u53e3\u4efb\u610f\u4f4d\u7f6e\u62d6\u52a8\n        self.x = event.x\n        self.y = event.y\n    \n    def do_move(self, event):\n        deltax = event.x - self.x\n        deltay = event.y - self.y\n        x = self.root.winfo_x() + deltax\n        y = self.root.winfo_y() + deltay\n        self.root.geometry(f\"+{x}+{y}\")\n    \n    @staticmethod\n    def encrypt_data(data):\n        \"\"\"\u52a0\u5bc6\u6570\u636e\"\"\"\n        # \u4f7f\u7528\u7b80\u5355\u7684\u5f02\u6216\u52a0\u5bc6\n        key = \"Ky1nSecretKey\"  # \u52a0\u5bc6\u5bc6\u94a5\n        encrypted = bytearray()\n        for i, char in enumerate(data.encode('utf-8')):\n            encrypted.append(char ^ ord(key&#91;i % len(key)]))\n        return base64.b64encode(encrypted).decode('utf-8')\n    \n    @staticmethod\n    def decrypt_data(data):\n        \"\"\"\u89e3\u5bc6\u6570\u636e\"\"\"\n        try:\n            encrypted = base64.b64decode(data.encode('utf-8'))\n            key = \"Ky1nSecretKey\"  # \u52a0\u5bc6\u5bc6\u94a5\n            decrypted = bytearray()\n            for i, char in enumerate(encrypted):\n                decrypted.append(char ^ ord(key&#91;i % len(key)]))\n            return decrypted.decode('utf-8')\n        except:\n            return None\n    \n    def load_lists(self):\n        \"\"\"\u52a0\u8f7d\u540d\u5355\u6587\u4ef6\uff0c\u8fd4\u56de\u662f\u5426\u6210\u529f\"\"\"\n        self.lists = {}\n        list_names = &#91;]\n        decryption_failed = False\n        \n        for i in range(1, 9):\n            filename = f\"nameinfo\/name.info{i}\"\n            if os.path.exists(filename):\n                try:\n                    with open(filename, \"r\", encoding=\"utf-8\") as f:\n                        encrypted_content = f.read()\n                    \n                    # \u89e3\u5bc6\u5185\u5bb9\n                    decrypted_content = RandomPickerApp.decrypt_data(encrypted_content)\n                    if decrypted_content is None:\n                        print(f\"\u89e3\u5bc6\u540d\u5355 {filename} \u5931\u8d25\")\n                        decryption_failed = True\n                        continue\n                    \n                    lines = decrypted_content.splitlines()\n                    \n                    if len(lines) >= 2:\n                        list_name = lines&#91;0].strip()\n                        try:\n                            count = int(lines&#91;1].strip())\n                        except ValueError:\n                            count = 0\n                        \n                        names = &#91;line.strip() for line in lines&#91;2:2+count] if line.strip()]\n                        self.lists&#91;filename] = {\n                            \"name\": list_name,\n                            \"count\": count,\n                            \"names\": names\n                        }\n                        list_names.append(list_name)\n                except Exception as e:\n                    print(f\"\u52a0\u8f7d\u540d\u5355 {filename} \u51fa\u9519: {e}\")\n                    decryption_failed = True\n        \n        # \u66f4\u65b0\u4e0b\u62c9\u83dc\u5355\n        self.list_combobox&#91;\"values\"] = list_names\n        if list_names:\n            self.list_var.set(list_names&#91;0])\n            self.on_list_selected()\n        \n        # \u5982\u679c\u6709\u89e3\u5bc6\u5931\u8d25\u7684\u6587\u4ef6\uff0c\u8fd4\u56deFalse\n        return not decryption_failed\n    \n    def show_decryption_error_dialog(self):\n        \"\"\"\u663e\u793a\u89e3\u5bc6\u9519\u8bef\u5bf9\u8bdd\u6846\"\"\"\n        # \u521b\u5efa\u9519\u8bef\u5bf9\u8bdd\u6846\n        error_dialog = tk.Toplevel(self.root)\n        error_dialog.title(\"\u6570\u636e\u9519\u8bef\")\n        error_dialog.geometry(\"300x150\")\n        error_dialog.resizable(False, False)\n        error_dialog.transient(self.root)\n        error_dialog.grab_set()\n        \n        # \u5c45\u4e2d\u663e\u793a\n        error_dialog.update_idletasks()\n        x = (error_dialog.winfo_screenwidth() - error_dialog.winfo_width()) \/\/ 2\n        y = (error_dialog.winfo_screenheight() - error_dialog.winfo_height()) \/\/ 2\n        error_dialog.geometry(f\"+{x}+{y}\")\n        \n        # \u9519\u8bef\u4fe1\u606f\n        error_label = ttk.Label(\n            error_dialog, \n            text=\"\u6570\u636e\u6587\u4ef6\u5df2\u635f\u574f\u6216\u5df2\u88ab\u7be1\u6539\uff01\\n\u8bf7\u9009\u62e9\u64cd\u4f5c\uff1a\",\n            font=(\"Arial\", 10),\n            justify=tk.CENTER\n        )\n        error_label.pack(pady=20)\n        \n        # \u6309\u94ae\u6846\u67b6\n        button_frame = ttk.Frame(error_dialog)\n        button_frame.pack(pady=10)\n        \n        # \u9000\u51fa\u6309\u94ae\n        exit_button = ttk.Button(\n            button_frame, \n            text=\"\u9000\u51fa\u7a0b\u5e8f\", \n            command=lambda: self.exit_program(error_dialog),\n            width=12\n        )\n        exit_button.pack(side=tk.LEFT, padx=10)\n        \n        # \u91cd\u7f6e\u6309\u94ae\n        reset_button = ttk.Button(\n            button_frame, \n            text=\"\u91cd\u7f6e\u540d\u5355\", \n            command=lambda: self.reset_lists(error_dialog),\n            width=12\n        )\n        reset_button.pack(side=tk.LEFT, padx=10)\n    \n    def exit_program(self, dialog):\n        \"\"\"\u9000\u51fa\u7a0b\u5e8f\"\"\"\n        if dialog:\n            dialog.destroy()\n        self.root.quit()\n        self.root.destroy()\n    \n    def reset_lists(self, dialog):\n        \"\"\"\u91cd\u7f6e\u540d\u5355\u6587\u4ef6\"\"\"\n        try:\n            # \u5907\u4efd\u539f\u6587\u4ef6\uff08\u5982\u679c\u5b58\u5728\uff09\n            if os.path.exists(\"nameinfo\"):\n                backup_dir = \"nameinfo_backup_\" + time.strftime(\"%Y%m%d_%H%M%S\")\n                shutil.copytree(\"nameinfo\", backup_dir)\n            \n            # \u5220\u9664\u539f\u76ee\u5f55\n            if os.path.exists(\"nameinfo\"):\n                shutil.rmtree(\"nameinfo\")\n            \n            # \u91cd\u65b0\u521b\u5efa\u76ee\u5f55\u548c\u793a\u4f8b\u6587\u4ef6\n            os.makedirs(\"nameinfo\")\n            self.create_sample_files()\n            \n            # \u91cd\u65b0\u52a0\u8f7d\u540d\u5355\n            if self.load_lists():\n                if dialog:\n                    dialog.destroy()\n                messagebox.showinfo(\"\u6210\u529f\", \"\u540d\u5355\u5df2\u91cd\u7f6e\u4e3a\u9ed8\u8ba4\u503c\u3002\")\n            else:\n                messagebox.showerror(\"\u9519\u8bef\", \"\u91cd\u7f6e\u540d\u5355\u5931\u8d25\uff0c\u8bf7\u91cd\u8bd5\u3002\")\n        except Exception as e:\n            messagebox.showerror(\"\u9519\u8bef\", f\"\u91cd\u7f6e\u540d\u5355\u65f6\u51fa\u9519: {str(e)}\")\n    \n    def create_sample_files(self):\n        \"\"\"\u521b\u5efa\u793a\u4f8b\u540d\u5355\u6587\u4ef6\"\"\"\n        for i in range(1, 9):\n            filename = f\"nameinfo\/name.info{i}\"\n            # \u6784\u5efa\u6587\u4ef6\u5185\u5bb9\n            content = f\"\u540d\u5355{i}\\n5\\n\"\n            for j in range(1, 6):\n                content += f\"\u4eba\u5458{i}-{j}\\n\"\n            \n            # \u4f7f\u7528\u9759\u6001\u65b9\u6cd5\u52a0\u5bc6\n            encrypted_content = RandomPickerApp.encrypt_data(content)\n            \n            with open(filename, \"w\", encoding=\"utf-8\") as f:\n                f.write(encrypted_content)\n    \n    def on_list_selected(self, event=None):\n        selected_name = self.list_var.get()\n        for filename, data in self.lists.items():\n            if data&#91;\"name\"] == selected_name:\n                self.current_list = filename\n                break\n        else:\n            self.current_list = None\n    \n    def pick_random(self):\n        if not self.current_list:\n            return\n        \n        list_data = self.lists.get(self.current_list)\n        if not list_data:\n            return\n        \n        if list_data&#91;\"count\"] &lt;= 0:\n            self.result_label.config(text=\"Error\", foreground=\"red\")\n            return\n        \n        if not list_data&#91;\"names\"]:\n            self.result_label.config(text=\"\u540d\u5355\u4e3a\u7a7a\", foreground=\"orange\")\n            return\n        \n        # \u7981\u7528\u62bd\u53d6\u6309\u94ae\n        self.pick_button.config(state=tk.DISABLED)\n        \n        # \u52a8\u753b\u6548\u679c\uff1a\u5feb\u901f\u62bd\u53d620\u6b21\n        original_names = list_data&#91;\"names\"]\n        for i in range(20):\n            # \u968f\u673a\u9009\u62e9\u4e00\u4e2a\u4eba\n            selected = random.choice(original_names)\n            self.result_label.config(text=selected, foreground=\"purple\")\n            self.root.update()\n            time.sleep(0.04)  # \u95f4\u96940.04\u79d2\n        \n        # \u6700\u7ec8\u9009\u62e9\u4e00\u4e2a\u4eba\n        selected = random.choice(original_names)\n        self.result_label.config(text=selected, foreground=\"green\")\n        \n        # \u542f\u7528\u62bd\u53d6\u6309\u94ae\n        self.pick_button.config(state=tk.NORMAL)\n    \n    def toggle_topmost(self):\n        self.topmost = not self.topmost\n        self.root.attributes(\"-topmost\", self.topmost)\n        self.update_top_button()\n    \n    def update_top_button(self):\n        text = \"\u53d6\u6d88\u7f6e\u9876\" if self.topmost else \"\u7f6e\u9876\"\n        self.top_button.config(text=text)\n    \n    def open_edit_window(self):\n        EditWindow(self)\n    \n    def hide_window(self):\n        # \u83b7\u53d6\u7a97\u53e3\u4f4d\u7f6e\n        x = self.root.winfo_x()\n        y = self.root.winfo_y()\n        screen_width = self.root.winfo_screenwidth()\n        \n        # \u5224\u65ad\u7a97\u53e3\u5728\u5c4f\u5e55\u5de6\u4fa7\u8fd8\u662f\u53f3\u4fa7\n        if x &lt; screen_width \/ 2:\n            # \u5de6\u4fa7\n            position = (0, y)\n        else:\n            # \u53f3\u4fa7\n            position = (screen_width - 50, y)  # \u589e\u52a0\u5bbd\u5ea6\u786e\u4fdd\u663e\u793a\u5b8c\u6574\n        \n        # \u9690\u85cf\u4e3b\u7a97\u53e3\n        self.root.withdraw()\n        self.hidden = True\n        \n        # \u521b\u5efa\u7f8e\u89c2\u7684\u62bd\u4eba\u6309\u94ae\n        self.create_beautiful_button(position)\n    \n    def create_beautiful_button(self, position):\n        self.compact_button_window = tk.Toplevel()\n        self.compact_button_window.overrideredirect(True)  # \u65e0\u8fb9\u6846\n        self.compact_button_window.attributes(\"-topmost\", True)\n        \n        # \u8bbe\u7f6e\u4f4d\u7f6e\u548c\u5927\u5c0f\uff08\u589e\u52a0\u9ad8\u5ea6\u786e\u4fdd\u6587\u5b57\u5b8c\u6574\u663e\u793a\uff09\n        self.compact_button_window.geometry(f\"50x60+{position&#91;0]}+{position&#91;1]}\")\n        \n        # \u8bbe\u7f6e\u80cc\u666f\u8272\n        bg_color = \"#f0f0f0\"  # \u6d45\u7070\u8272\u80cc\u666f\n        \n        # \u521b\u5efa\u4e3b\u6846\u67b6 - \u7528\u4e8e\u5b9e\u73b0\u5706\u89d2\u6548\u679c\n        main_frame = tk.Frame(\n            self.compact_button_window, \n            bg=bg_color,\n            highlightbackground=\"#c0c0c0\",  # \u8fb9\u6846\u989c\u8272\n            highlightthickness=1  # \u8fb9\u6846\u539a\u5ea6\n        )\n        main_frame.pack(fill=tk.BOTH, expand=True, padx=1, pady=1)\n        \n        # \u521b\u5efaCanvas\u7528\u4e8e\u7ed8\u5236\u5706\u89d2\n        canvas = tk.Canvas(\n            main_frame,\n            width=48,  # \u6bd4\u6846\u67b6\u5c0f2\u50cf\u7d20\n            height=58,  # \u6bd4\u6846\u67b6\u5c0f2\u50cf\u7d20\n            bg=bg_color,\n            highlightthickness=0  # \u65e0\u8fb9\u6846\n        )\n        canvas.pack(fill=tk.BOTH, expand=True)\n        \n        # \u7ed8\u5236\u5706\u89d2\u77e9\u5f62\n        canvas.create_rounded_rectangle(\n            0, 0, 48, 58, \n            radius=10,  # \u5706\u89d2\u534a\u5f84\n            fill=bg_color,\n            outline=\"#c0c0c0\"\n        )\n        \n        # \u521b\u5efa\u7d27\u51d1\u5e03\u5c40\uff1a\"\u62bd\"\u5728\u4e0a\uff0c\"\u4eba\"\u5728\u4e0b\n        top_label = tk.Label(\n            canvas,\n            text=\"\u62bd\",\n            font=(\"Arial\", 14, \"bold\"),\n            anchor=tk.CENTER,\n            bg=bg_color,\n            fg=\"#333333\"  # \u6df1\u7070\u8272\u6587\u5b57\n        )\n        # \u653e\u7f6e\u6807\u7b7e - \u786e\u4fdd\u4f4d\u7f6e\u5c45\u4e2d\n        top_label.place(relx=0.5, rely=0.3, anchor=tk.CENTER)  # \u4e0a\u79fb\u4f4d\u7f6e\n        \n        bottom_label = tk.Label(\n            canvas,\n            text=\"\u4eba\",\n            font=(\"Arial\", 14, \"bold\"),\n            anchor=tk.CENTER,\n            bg=bg_color,\n            fg=\"#333333\"  # \u6df1\u7070\u8272\u6587\u5b57\n        )\n        # \u653e\u7f6e\u6807\u7b7e - \u786e\u4fdd\u4f4d\u7f6e\u5c45\u4e2d\n        bottom_label.place(relx=0.5, rely=0.7, anchor=tk.CENTER)  # \u4e0b\u79fb\u4f4d\u7f6e\n        \n        # \u4e3a\u6574\u4e2a\u7a97\u53e3\u7ed1\u5b9a\u70b9\u51fb\u4e8b\u4ef6\n        self.compact_button_window.bind(\"&lt;Button-1>\", lambda e: self.show_main_window())\n        \n        # \u6dfb\u52a0\u60ac\u505c\u6548\u679c\n        def on_enter(e):\n            canvas.config(bg=\"#e0e0e0\")\n            top_label.config(bg=\"#e0e0e0\")\n            bottom_label.config(bg=\"#e0e0e0\")\n            # \u91cd\u7ed8\u5706\u89d2\u77e9\u5f62\n            canvas.delete(\"all\")\n            canvas.create_rounded_rectangle(\n                0, 0, 48, 58, \n                radius=10,\n                fill=\"#e0e0e0\",\n                outline=\"#c0c0c0\"\n            )\n            # \u91cd\u65b0\u653e\u7f6e\u6807\u7b7e\n            top_label.place(relx=0.5, rely=0.3, anchor=tk.CENTER)\n            bottom_label.place(relx=0.5, rely=0.7, anchor=tk.CENTER)\n        \n        def on_leave(e):\n            canvas.config(bg=bg_color)\n            top_label.config(bg=bg_color)\n            bottom_label.config(bg=bg_color)\n            # \u91cd\u7ed8\u5706\u89d2\u77e9\u5f62\n            canvas.delete(\"all\")\n            canvas.create_rounded_rectangle(\n                0, 0, 48, 58, \n                radius=10,\n                fill=bg_color,\n                outline=\"#c0c0c0\"\n            )\n            # \u91cd\u65b0\u653e\u7f6e\u6807\u7b7e\n            top_label.place(relx=0.5, rely=0.3, anchor=tk.CENTER)\n            bottom_label.place(relx=0.5, rely=0.7, anchor=tk.CENTER)\n        \n        self.compact_button_window.bind(\"&lt;Enter>\", on_enter)\n        self.compact_button_window.bind(\"&lt;Leave>\", on_leave)\n    \n    def show_main_window(self):\n        # \u9500\u6bc1\u7d27\u51d1\u6309\u94ae\u7a97\u53e3\n        self.compact_button_window.destroy()\n        \n        # \u663e\u793a\u4e3b\u7a97\u53e3\n        self.root.deiconify()\n        self.hidden = False\n    \n    def save_list(self, filename, list_name, names):\n        count = len(names)\n        # \u6784\u5efa\u6587\u4ef6\u5185\u5bb9\n        content = f\"{list_name}\\n{count}\\n\"\n        content += \"\\n\".join(names)\n        \n        # \u52a0\u5bc6\u5185\u5bb9\n        encrypted_content = RandomPickerApp.encrypt_data(content)\n        \n        with open(filename, \"w\", encoding=\"utf-8\") as f:\n            f.write(encrypted_content)\n        \n        # \u91cd\u65b0\u52a0\u8f7d\u540d\u5355\n        self.load_lists()\n        \n        # \u66f4\u65b0\u5f53\u524d\u9009\u62e9\n        if self.current_list == filename:\n            self.list_var.set(list_name)\n\n\n# \u4e3aCanvas\u6dfb\u52a0\u7ed8\u5236\u5706\u89d2\u77e9\u5f62\u7684\u65b9\u6cd5\ndef create_rounded_rectangle(self, x1, y1, x2, y2, radius=25, **kwargs):\n    points = &#91;\n        x1 + radius, y1,\n        x1 + radius, y1,\n        x2 - radius, y1,\n        x2 - radius, y1,\n        x2, y1,\n        x2, y1 + radius,\n        x2, y1 + radius,\n        x2, y2 - radius,\n        x2, y2 - radius,\n        x2, y2,\n        x2 - radius, y2,\n        x2 - radius, y2,\n        x1 + radius, y2,\n        x1 + radius, y2,\n        x1, y2,\n        x1, y2 - radius,\n        x1, y2 - radius,\n        x1, y1 + radius,\n        x1, y1 + radius,\n        x1, y1,\n        x1 + radius, y1\n    ]\n    \n    return self.create_polygon(points, **kwargs, smooth=True)\n\n# \u5c06\u65b9\u6cd5\u6dfb\u52a0\u5230Canvas\u7c7b\ntk.Canvas.create_rounded_rectangle = create_rounded_rectangle\n\n\nclass EditWindow:\n    def __init__(self, app):\n        self.app = app\n        self.window = tk.Toplevel(app.root)\n        self.window.title(\"\u7f16\u8f91\u540d\u5355\")\n        \n        # \u8bbe\u7f6e\u7f16\u8f91\u754c\u9762\u5927\u5c0f\u4e3a100x300\n        self.window.geometry(\"100x300\")\n        self.window.minsize(100, 300)\n        \n        self.window.transient(app.root)\n        self.window.grab_set()\n        \n        # \u521b\u5efa\u7b14\u8bb0\u672c\u5f0f\u6807\u7b7e\u9875\n        self.notebook = ttk.Notebook(self.window)\n        self.notebook.pack(fill=tk.BOTH, expand=True, padx=2, pady=2)\n        \n        # \u4e3a\u6bcf\u4e2a\u540d\u5355\u521b\u5efa\u6807\u7b7e\u9875\n        self.tabs = {}\n        self.list_vars = {}\n        self.text_widgets = {}\n        \n        for i in range(1, 9):\n            filename = f\"nameinfo\/name.info{i}\"\n            tab = ttk.Frame(self.notebook)\n            self.notebook.add(tab, text=str(i))  # \u53ea\u663e\u793a\u6570\u5b57\u6807\u7b7e\u8282\u7701\u7a7a\u95f4\n            self.tabs&#91;filename] = tab\n            \n            # \u540d\u5355\u540d\u79f0\u7f16\u8f91\n            name_frame = ttk.Frame(tab)\n            name_frame.pack(fill=tk.X, padx=2, pady=2)\n            \n            list_var = tk.StringVar()\n            self.list_vars&#91;filename] = list_var\n            \n            name_entry = ttk.Entry(name_frame, textvariable=list_var, width=8)\n            name_entry.pack(fill=tk.X, padx=2)\n            \n            # \u6dfb\u52a0\u63d0\u793a\u6807\u7b7e\n            tip_label = ttk.Label(\n                tab, \n                text=\"\u4e00\u884c\u4e00\u4e2a\u540d\u5b57\", \n                font=(\"Arial\", 6),  # \u4f7f\u7528\u975e\u5e38\u5c0f\u7684\u5b57\u4f53\n                foreground=\"gray\",\n                anchor=tk.CENTER\n            )\n            tip_label.pack(fill=tk.X, padx=2, pady=(0, 2))\n            \n            # \u540d\u5355\u5185\u5bb9\u7f16\u8f91\n            text_frame = ttk.Frame(tab)\n            text_frame.pack(fill=tk.BOTH, expand=True, padx=2, pady=2)\n            \n            scrollbar = ttk.Scrollbar(text_frame)\n            scrollbar.pack(side=tk.RIGHT, fill=tk.Y)\n            \n            text_widget = tk.Text(\n                text_frame, \n                wrap=tk.WORD, \n                yscrollcommand=scrollbar.set,\n                font=(\"Arial\", 8),  # \u4f7f\u7528\u66f4\u5c0f\u7684\u5b57\u4f53\n                height=8\n            )\n            text_widget.pack(fill=tk.BOTH, expand=True)\n            \n            scrollbar.config(command=text_widget.yview)\n            self.text_widgets&#91;filename] = text_widget\n            \n            # \u6309\u94ae\u533a\u57df\n            button_frame = ttk.Frame(tab)\n            button_frame.pack(fill=tk.X, padx=2, pady=2)\n            \n            save_button = ttk.Button(\n                button_frame, \n                text=\"\u4fdd\u5b58\", \n                command=lambda f=filename: self.save_list(f),\n                width=5\n            )\n            save_button.pack(side=tk.LEFT, padx=1)\n            \n            clear_button = ttk.Button(\n                button_frame, \n                text=\"\u6e05\u7a7a\", \n                command=lambda f=filename: self.clear_list(f),\n                width=5\n            )\n            clear_button.pack(side=tk.LEFT, padx=1)\n        \n        # \u52a0\u8f7d\u6570\u636e\u5230\u754c\u9762\n        self.load_data()\n        \n        # \u8bbe\u7f6e\u5173\u95ed\u7a97\u53e3\u4e8b\u4ef6\n        self.window.protocol(\"WM_DELETE_WINDOW\", self.on_close)\n    \n    def load_data(self):\n        for filename, tab in self.tabs.items():\n            if filename in self.app.lists:\n                data = self.app.lists&#91;filename]\n                self.list_vars&#91;filename].set(data&#91;\"name\"])\n                \n                text_widget = self.text_widgets&#91;filename]\n                text_widget.delete(1.0, tk.END)\n                text_widget.insert(tk.END, \"\\n\".join(data&#91;\"names\"]))\n            else:\n                self.list_vars&#91;filename].set(f\"\u540d\u5355{filename&#91;-1]}\")\n                self.text_widgets&#91;filename].delete(1.0, tk.END)\n    \n    def save_list(self, filename):\n        list_name = self.list_vars&#91;filename].get()\n        if not list_name:\n            return\n        \n        text_content = self.text_widgets&#91;filename].get(1.0, tk.END)\n        names = &#91;name.strip() for name in text_content.splitlines() if name.strip()]\n        \n        self.app.save_list(filename, list_name, names)\n    \n    def clear_list(self, filename):\n        if messagebox.askyesno(\"\u786e\u8ba4\", \"\u786e\u5b9a\u8981\u6e05\u7a7a\u6b64\u540d\u5355\u5417\uff1f\"):\n            self.text_widgets&#91;filename].delete(1.0, tk.END)\n    \n    def on_close(self):\n        self.window.grab_release()\n        self.window.destroy()\n\n\nif __name__ == \"__main__\":\n    # \u786e\u4fddnameinfo\u76ee\u5f55\u5b58\u5728\n    if not os.path.exists(\"nameinfo\"):\n        os.makedirs(\"nameinfo\")\n    \n    # \u521b\u5efa\u793a\u4f8b\u540d\u5355\u6587\u4ef6\uff08\u5982\u679c\u4e0d\u5b58\u5728\uff09\n    for i in range(1, 9):\n        filename = f\"nameinfo\/name.info{i}\"\n        if not os.path.exists(filename):\n            # \u6784\u5efa\u6587\u4ef6\u5185\u5bb9\n            content = f\"\u540d\u5355{i}\\n5\\n\"\n            for j in range(1, 6):\n                content += f\"\u4eba\u5458{i}-{j}\\n\"\n            \n            # \u4f7f\u7528\u9759\u6001\u65b9\u6cd5\u52a0\u5bc6\n            encrypted_content = RandomPickerApp.encrypt_data(content)\n            \n            with open(filename, \"w\", encoding=\"utf-8\") as f:\n                f.write(encrypted_content)\n    \n    root = tk.Tk()\n    app = RandomPickerApp(root)\n    root.mainloop()\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u57fa\u4e8ePython 3 Tkinter\u5f00\u53d1\u7684\u4e00\u6b3e\u591a\u540d\u5355\u52a0\u5bc6\u62bd\u4eba\u8f6f\u4ef6\u2014\u2014\u81ea\u52a8\u62bd\u4ebav3.0\u7248 base\u52a0\u5bc6v1.0\u7248 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":77,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[],"class_list":["post-72","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-15"],"_links":{"self":[{"href":"https:\/\/ky1n.cn\/index.php\/wp-json\/wp\/v2\/posts\/72","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ky1n.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ky1n.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ky1n.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ky1n.cn\/index.php\/wp-json\/wp\/v2\/comments?post=72"}],"version-history":[{"count":8,"href":"https:\/\/ky1n.cn\/index.php\/wp-json\/wp\/v2\/posts\/72\/revisions"}],"predecessor-version":[{"id":82,"href":"https:\/\/ky1n.cn\/index.php\/wp-json\/wp\/v2\/posts\/72\/revisions\/82"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ky1n.cn\/index.php\/wp-json\/wp\/v2\/media\/77"}],"wp:attachment":[{"href":"https:\/\/ky1n.cn\/index.php\/wp-json\/wp\/v2\/media?parent=72"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ky1n.cn\/index.php\/wp-json\/wp\/v2\/categories?post=72"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ky1n.cn\/index.php\/wp-json\/wp\/v2\/tags?post=72"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}