Utoljára aktív 1 month ago

Revízió a9dd8a4f5307f0aa8051211b3d27cda8b8e921e2

winget.png Eredeti
winget.png
winget_gui.py Eredeti
1"""
2Winget Manager GUI - Пълно функционално приложение
3Изисквания: pip install customtkinter
4"""
5
6import customtkinter as ctk
7import subprocess
8import threading
9from tkinter import messagebox
10import sys
11
12class WingetGUI(ctk.CTk):
13 def __init__(self):
14 super().__init__()
15
16 # Конфигурация на прозореца
17 self.title("Winget Manager Pro")
18 self.geometry("1200x800")
19 ctk.set_appearance_mode("dark")
20 ctk.set_default_color_theme("blue")
21
22 # Проверка за winget
23 if not self.check_winget():
24 messagebox.showerror("Грешка", "Winget не е намерен! Моля, инсталирайте App Installer от Microsoft Store.")
25 sys.exit(1)
26
27 # Основен контейнер
28 self.grid_columnconfigure(1, weight=1)
29 self.grid_rowconfigure(0, weight=1)
30
31 # Странична навигация
32 self.create_sidebar()
33
34 # Основно съдържание
35 self.create_main_content()
36
37 # Статус бар
38 self.create_status_bar()
39
40 def check_winget(self):
41 """Проверява дали winget е инсталиран"""
42 try:
43 subprocess.run(["winget", "--version"],
44 capture_output=True,
45 timeout=5,
46 creationflags=subprocess.CREATE_NO_WINDOW)
47 return True
48 except:
49 return False
50
51 def create_sidebar(self):
52 """Създава странична навигация"""
53 self.sidebar = ctk.CTkFrame(self, width=200, corner_radius=0)
54 self.sidebar.grid(row=0, column=0, sticky="nsew", padx=0, pady=0)
55 self.sidebar.grid_rowconfigure(7, weight=1)
56
57 # Лого
58 self.logo_label = ctk.CTkLabel(
59 self.sidebar,
60 text="🚀 Winget Manager",
61 font=ctk.CTkFont(size=20, weight="bold")
62 )
63 self.logo_label.grid(row=0, column=0, padx=20, pady=(20, 30))
64
65 # Бутони за навигация
66 self.nav_buttons = {}
67 nav_items = [
68 ("🔍 Търсене", "search"),
69 ("📥 Инсталиране", "install"),
70 ("🔄 Обновяване", "upgrade"),
71 ("🗑️ Деинсталиране", "uninstall"),
72 ("📋 Списък", "list"),
73 ("ℹ️ Информация", "info"),
74 ("🖥️ Терминал", "terminal"),
75 ]
76
77 for idx, (text, key) in enumerate(nav_items, start=1):
78 btn = ctk.CTkButton(
79 self.sidebar,
80 text=text,
81 command=lambda k=key: self.show_tab(k),
82 height=40,
83 font=ctk.CTkFont(size=14)
84 )
85 btn.grid(row=idx, column=0, padx=20, pady=10, sticky="ew")
86 self.nav_buttons[key] = btn
87
88 # Бутон за изчистване
89 self.clear_btn = ctk.CTkButton(
90 self.sidebar,
91 text="🧹 Изчисти изход",
92 command=self.clear_output,
93 fg_color="transparent",
94 border_width=2,
95 height=40
96 )
97 self.clear_btn.grid(row=9, column=0, padx=20, pady=20, sticky="ew")
98
99 def create_main_content(self):
100 """Създава основното съдържание"""
101 self.main_frame = ctk.CTkFrame(self, corner_radius=0)
102 self.main_frame.grid(row=0, column=1, sticky="nsew", padx=0, pady=0)
103 self.main_frame.grid_rowconfigure(1, weight=1)
104 self.main_frame.grid_columnconfigure(0, weight=1)
105
106 # Контейнер за табове
107 self.tabs_container = ctk.CTkFrame(self.main_frame)
108 self.tabs_container.grid(row=0, column=0, sticky="ew", padx=20, pady=20)
109 self.tabs_container.grid_columnconfigure(0, weight=1)
110
111 # Създаване на табове
112 self.tabs = {}
113 self.create_search_tab()
114 self.create_install_tab()
115 self.create_upgrade_tab()
116 self.create_uninstall_tab()
117 self.create_list_tab()
118 self.create_info_tab()
119 self.create_terminal_tab()
120
121 # Терминален изход (само за GUI табовете)
122 self.output_label = ctk.CTkLabel(
123 self.main_frame,
124 text="📟 Терминален изход",
125 font=ctk.CTkFont(size=16, weight="bold")
126 )
127 self.output_label.grid(row=2, column=0, padx=20, pady=(20, 5), sticky="w")
128
129 self.output_text = ctk.CTkTextbox(
130 self.main_frame,
131 height=350,
132 font=("Consolas", 13),
133 wrap="word"
134 )
135 self.output_text.grid(row=3, column=0, sticky="nsew", padx=20, pady=(0, 20))
136
137 # Показване на първия таб
138 self.show_tab("search")
139
140 def create_search_tab(self):
141 """Таб за търсене"""
142 tab = ctk.CTkFrame(self.tabs_container, fg_color="transparent")
143 self.tabs["search"] = tab
144
145 ctk.CTkLabel(tab, text="🔍 Търсене на пакети",
146 font=ctk.CTkFont(size=18, weight="bold")).grid(
147 row=0, column=0, padx=10, pady=10, sticky="w")
148
149 self.search_entry = ctk.CTkEntry(
150 tab,
151 placeholder_text="Въведете име на пакет (напр. chrome, firefox)...",
152 height=40,
153 font=ctk.CTkFont(size=13)
154 )
155 self.search_entry.grid(row=1, column=0, padx=10, pady=10, sticky="ew")
156 self.search_entry.bind("<Return>", lambda e: self.search_packages())
157
158 ctk.CTkButton(
159 tab,
160 text="🔍 Търси",
161 command=self.search_packages,
162 height=40,
163 font=ctk.CTkFont(size=14, weight="bold")
164 ).grid(row=2, column=0, padx=10, pady=10, sticky="ew")
165
166 tab.grid_columnconfigure(0, weight=1)
167
168 def create_install_tab(self):
169 """Таб за инсталиране"""
170 tab = ctk.CTkFrame(self.tabs_container, fg_color="transparent")
171 self.tabs["install"] = tab
172
173 ctk.CTkLabel(tab, text="📥 Инсталиране на пакет",
174 font=ctk.CTkFont(size=18, weight="bold")).grid(
175 row=0, column=0, padx=10, pady=10, sticky="w")
176
177 self.install_entry = ctk.CTkEntry(
178 tab,
179 placeholder_text="Въведете точния ID (напр. Google.Chrome)...",
180 height=40,
181 font=ctk.CTkFont(size=13)
182 )
183 self.install_entry.grid(row=1, column=0, padx=10, pady=10, sticky="ew")
184 self.install_entry.bind("<Return>", lambda e: self.install_package())
185
186 ctk.CTkButton(
187 tab,
188 text="📥 Инсталирай",
189 command=self.install_package,
190 height=40,
191 fg_color="green",
192 hover_color="darkgreen",
193 font=ctk.CTkFont(size=14, weight="bold")
194 ).grid(row=2, column=0, padx=10, pady=10, sticky="ew")
195
196 ctk.CTkLabel(
197 tab,
198 text="💡 Използвайте таб 'Търсене' за намиране на точния ID",
199 font=ctk.CTkFont(size=11),
200 text_color="gray"
201 ).grid(row=3, column=0, padx=10, pady=5, sticky="w")
202
203 tab.grid_columnconfigure(0, weight=1)
204
205 def create_upgrade_tab(self):
206 """Таб за обновяване"""
207 tab = ctk.CTkFrame(self.tabs_container, fg_color="transparent")
208 self.tabs["upgrade"] = tab
209
210 ctk.CTkLabel(tab, text="🔄 Обновяване на пакети",
211 font=ctk.CTkFont(size=18, weight="bold")).grid(
212 row=0, column=0, padx=10, pady=10, sticky="w")
213
214 ctk.CTkButton(
215 tab,
216 text="🔄 Обнови всички пакети",
217 command=self.upgrade_all,
218 height=50,
219 fg_color="#1e88e5",
220 hover_color="#1565c0",
221 font=ctk.CTkFont(size=15, weight="bold")
222 ).grid(row=1, column=0, padx=10, pady=15, sticky="ew")
223
224 ctk.CTkLabel(
225 tab,
226 text="── или обнови конкретен пакет ──",
227 font=ctk.CTkFont(size=12),
228 text_color="gray"
229 ).grid(row=2, column=0, padx=10, pady=10)
230
231 self.upgrade_entry = ctk.CTkEntry(
232 tab,
233 placeholder_text="ID на пакет (напр. Microsoft.VisualStudioCode)...",
234 height=40,
235 font=ctk.CTkFont(size=13)
236 )
237 self.upgrade_entry.grid(row=3, column=0, padx=10, pady=10, sticky="ew")
238 self.upgrade_entry.bind("<Return>", lambda e: self.upgrade_package())
239
240 ctk.CTkButton(
241 tab,
242 text="🔄 Обнови",
243 command=self.upgrade_package,
244 height=40,
245 font=ctk.CTkFont(size=14, weight="bold")
246 ).grid(row=4, column=0, padx=10, pady=10, sticky="ew")
247
248 tab.grid_columnconfigure(0, weight=1)
249
250 def create_uninstall_tab(self):
251 """Таб за деинсталиране"""
252 tab = ctk.CTkFrame(self.tabs_container, fg_color="transparent")
253 self.tabs["uninstall"] = tab
254
255 ctk.CTkLabel(tab, text="🗑️ Деинсталиране на пакет",
256 font=ctk.CTkFont(size=18, weight="bold")).grid(
257 row=0, column=0, padx=10, pady=10, sticky="w")
258
259 self.uninstall_entry = ctk.CTkEntry(
260 tab,
261 placeholder_text="Въведете ID на пакет (напр. Google.Chrome)...",
262 height=40,
263 font=ctk.CTkFont(size=13)
264 )
265 self.uninstall_entry.grid(row=1, column=0, padx=10, pady=10, sticky="ew")
266 self.uninstall_entry.bind("<Return>", lambda e: self.uninstall_package())
267
268 ctk.CTkButton(
269 tab,
270 text="🗑️ Деинсталирай",
271 command=self.uninstall_package,
272 height=40,
273 fg_color="red",
274 hover_color="darkred",
275 font=ctk.CTkFont(size=14, weight="bold")
276 ).grid(row=2, column=0, padx=10, pady=10, sticky="ew")
277
278 ctk.CTkLabel(
279 tab,
280 text="⚠️ Внимание: Операцията ще премахне приложението от системата",
281 font=ctk.CTkFont(size=11),
282 text_color="#ff6b6b"
283 ).grid(row=3, column=0, padx=10, pady=5, sticky="w")
284
285 tab.grid_columnconfigure(0, weight=1)
286
287 def create_list_tab(self):
288 """Таб за списък"""
289 tab = ctk.CTkFrame(self.tabs_container, fg_color="transparent")
290 self.tabs["list"] = tab
291
292 ctk.CTkLabel(tab, text="📋 Списък на приложенията",
293 font=ctk.CTkFont(size=18, weight="bold")).grid(
294 row=0, column=0, padx=10, pady=10, sticky="w")
295
296 ctk.CTkButton(
297 tab,
298 text="📋 Покажи всички приложения",
299 command=self.list_packages,
300 height=45,
301 font=ctk.CTkFont(size=14, weight="bold")
302 ).grid(row=1, column=0, padx=10, pady=10, sticky="ew")
303
304 ctk.CTkLabel(
305 tab,
306 text="── или филтрирай списъка ──",
307 font=ctk.CTkFont(size=12),
308 text_color="gray"
309 ).grid(row=2, column=0, padx=10, pady=10)
310
311 self.filter_entry = ctk.CTkEntry(
312 tab,
313 placeholder_text="Филтър (напр. Microsoft, Git)...",
314 height=40,
315 font=ctk.CTkFont(size=13)
316 )
317 self.filter_entry.grid(row=3, column=0, padx=10, pady=10, sticky="ew")
318 self.filter_entry.bind("<Return>", lambda e: self.filter_packages())
319
320 ctk.CTkButton(
321 tab,
322 text="🔍 Филтрирай",
323 command=self.filter_packages,
324 height=40,
325 font=ctk.CTkFont(size=14, weight="bold")
326 ).grid(row=4, column=0, padx=10, pady=10, sticky="ew")
327
328 tab.grid_columnconfigure(0, weight=1)
329
330 def create_info_tab(self):
331 """Таб за информация"""
332 tab = ctk.CTkFrame(self.tabs_container, fg_color="transparent")
333 self.tabs["info"] = tab
334
335 ctk.CTkLabel(tab, text="ℹ️ Информация за пакет",
336 font=ctk.CTkFont(size=18, weight="bold")).grid(
337 row=0, column=0, padx=10, pady=10, sticky="w")
338
339 self.info_entry = ctk.CTkEntry(
340 tab,
341 placeholder_text="Въведете ID за подробности (напр. Microsoft.VisualStudioCode)...",
342 height=40,
343 font=ctk.CTkFont(size=13)
344 )
345 self.info_entry.grid(row=1, column=0, padx=10, pady=10, sticky="ew")
346 self.info_entry.bind("<Return>", lambda e: self.show_info())
347
348 ctk.CTkButton(
349 tab,
350 text="ℹ️ Покажи информация",
351 command=self.show_info,
352 height=40,
353 font=ctk.CTkFont(size=14, weight="bold")
354 ).grid(row=2, column=0, padx=10, pady=10, sticky="ew")
355
356 tab.grid_columnconfigure(0, weight=1)
357
358 def create_terminal_tab(self):
359 """Таб за интерактивен терминал"""
360 tab = ctk.CTkFrame(self.tabs_container, fg_color="transparent")
361 self.tabs["terminal"] = tab
362
363 # Конфигурация за разтегляне
364 tab.grid_rowconfigure(1, weight=1)
365 tab.grid_columnconfigure(0, weight=1)
366
367 # Заглавие
368 header_frame = ctk.CTkFrame(tab, fg_color="transparent")
369 header_frame.grid(row=0, column=0, sticky="ew", padx=10, pady=10)
370 header_frame.grid_columnconfigure(0, weight=1)
371
372 ctk.CTkLabel(
373 header_frame,
374 text="🖥️ Интерактивен Winget Терминал",
375 font=ctk.CTkFont(size=18, weight="bold")
376 ).grid(row=0, column=0, sticky="w")
377
378 ctk.CTkLabel(
379 header_frame,
380 text="💡 Пишете winget команди директно (напр. winget list, winget search chrome)",
381 font=ctk.CTkFont(size=11),
382 text_color="gray"
383 ).grid(row=1, column=0, sticky="w", pady=(5, 0))
384
385 # Терминален прозорец
386 self.terminal_output = ctk.CTkTextbox(
387 tab,
388 font=("Consolas", 13),
389 wrap="word"
390 )
391 self.terminal_output.grid(row=1, column=0, sticky="nsew", padx=10, pady=(10, 10))
392
393 # Поле за команда
394 command_frame = ctk.CTkFrame(tab, fg_color="transparent")
395 command_frame.grid(row=2, column=0, sticky="ew", padx=10, pady=(0, 10))
396 command_frame.grid_columnconfigure(1, weight=1)
397
398 ctk.CTkLabel(
399 command_frame,
400 text="$",
401 font=ctk.CTkFont(size=16, weight="bold"),
402 text_color="#00ff00"
403 ).grid(row=0, column=0, padx=(5, 10))
404
405 self.terminal_entry = ctk.CTkEntry(
406 command_frame,
407 placeholder_text="winget ...",
408 height=45,
409 font=ctk.CTkFont(size=13)
410 )
411 self.terminal_entry.grid(row=0, column=1, sticky="ew", padx=(0, 10))
412 self.terminal_entry.bind("<Return>", lambda e: self.execute_terminal_command())
413 self.terminal_entry.bind("<Up>", lambda e: self.history_up())
414 self.terminal_entry.bind("<Down>", lambda e: self.history_down())
415
416 ctk.CTkButton(
417 command_frame,
418 text="▶ Изпълни",
419 command=self.execute_terminal_command,
420 height=45,
421 width=120,
422 fg_color="#00aa00",
423 hover_color="#008800",
424 font=ctk.CTkFont(size=13, weight="bold")
425 ).grid(row=0, column=2)
426
427 # Бутони
428 button_frame = ctk.CTkFrame(tab, fg_color="transparent")
429 button_frame.grid(row=3, column=0, sticky="ew", padx=10, pady=(0, 10))
430
431 ctk.CTkButton(
432 button_frame,
433 text="🧹 Изчисти",
434 command=self.clear_terminal,
435 height=35,
436 width=120,
437 fg_color="transparent",
438 border_width=2
439 ).pack(side="left", padx=5)
440
441 ctk.CTkButton(
442 button_frame,
443 text="📋 Копирай изход",
444 command=self.copy_terminal_output,
445 height=35,
446 width=150,
447 fg_color="transparent",
448 border_width=2
449 ).pack(side="left", padx=5)
450
451 # История на командите
452 self.command_history = []
453 self.history_index = -1
454
455 # Инициализиране
456 self.terminal_output.insert("1.0", "═══════════════════════════════════════════════════════════\n")
457 self.terminal_output.insert("end", " 🖥️ Winget Интерактивен Терминал\n")
458 self.terminal_output.insert("end", "═══════════════════════════════════════════════════════════\n\n")
459 self.terminal_output.insert("end", "Добре дошли! Можете да изпълнявате всички winget команди.\n\n")
460 self.terminal_output.insert("end", "Примери:\n")
461 self.terminal_output.insert("end", " • winget search chrome\n")
462 self.terminal_output.insert("end", " • winget list\n")
463 self.terminal_output.insert("end", " • winget install --id Google.Chrome\n")
464 self.terminal_output.insert("end", " • winget upgrade --all\n\n")
465 self.terminal_output.insert("end", "Използвайте ↑↓ стрелки за история на командите.\n")
466 self.terminal_output.insert("end", "═══════════════════════════════════════════════════════════\n\n")
467
468 def execute_terminal_command(self):
469 """Изпълнява команда в терминала"""
470 command = self.terminal_entry.get().strip()
471 if not command:
472 return
473
474 # Добавяне в история
475 self.command_history.append(command)
476 self.history_index = len(self.command_history)
477
478 # Показване на командата
479 self.terminal_output.insert("end", f"$ {command}\n")
480 self.terminal_output.see("end")
481
482 # Изчистване на входа
483 self.terminal_entry.delete(0, "end")
484
485 # Изпълнение
486 def execute():
487 try:
488 process = subprocess.Popen(
489 command,
490 shell=True,
491 stdout=subprocess.PIPE,
492 stderr=subprocess.PIPE,
493 text=True,
494 encoding='utf-8',
495 errors='replace',
496 creationflags=subprocess.CREATE_NO_WINDOW
497 )
498
499 stdout, stderr = process.communicate()
500 output = stdout if stdout else stderr
501
502 self.terminal_output.insert("end", output)
503 self.terminal_output.insert("end", "\n")
504 self.terminal_output.see("end")
505
506 except Exception as e:
507 self.terminal_output.insert("end", f"❌ Грешка: {str(e)}\n\n")
508 self.terminal_output.see("end")
509
510 threading.Thread(target=execute, daemon=True).start()
511
512 def history_up(self):
513 """Навигация нагоре в историята"""
514 if self.command_history and self.history_index > 0:
515 self.history_index -= 1
516 self.terminal_entry.delete(0, "end")
517 self.terminal_entry.insert(0, self.command_history[self.history_index])
518
519 def history_down(self):
520 """Навигация надолу в историята"""
521 if self.command_history and self.history_index < len(self.command_history) - 1:
522 self.history_index += 1
523 self.terminal_entry.delete(0, "end")
524 self.terminal_entry.insert(0, self.command_history[self.history_index])
525 elif self.history_index == len(self.command_history) - 1:
526 self.history_index = len(self.command_history)
527 self.terminal_entry.delete(0, "end")
528
529 def clear_terminal(self):
530 """Изчиства терминала"""
531 self.terminal_output.delete("1.0", "end")
532 self.terminal_output.insert("1.0", "═══════════════════════════════════════════════════════════\n")
533 self.terminal_output.insert("end", " 🖥️ Терминалът е изчистен\n")
534 self.terminal_output.insert("end", "═══════════════════════════════════════════════════════════\n\n")
535
536 def copy_terminal_output(self):
537 """Копира изхода в клипборда"""
538 try:
539 output = self.terminal_output.get("1.0", "end")
540 self.clipboard_clear()
541 self.clipboard_append(output)
542 self.update_status("✅ Изходът е копиран в клипборда")
543 except Exception as e:
544 messagebox.showerror("Грешка", f"Не може да се копира: {str(e)}")
545
546 def create_status_bar(self):
547 """Създава статус бар"""
548 self.status_bar = ctk.CTkFrame(self, height=30, corner_radius=0)
549 self.status_bar.grid(row=1, column=0, columnspan=2, sticky="ew")
550
551 self.status_label = ctk.CTkLabel(
552 self.status_bar,
553 text="✅ Готов",
554 font=ctk.CTkFont(size=11)
555 )
556 self.status_label.pack(side="left", padx=10)
557
558 def show_tab(self, tab_name):
559 """Показва избрания таб"""
560 for name, tab in self.tabs.items():
561 tab.grid_forget()
562
563 self.tabs[tab_name].grid(row=0, column=0, sticky="nsew", padx=0, pady=0)
564
565 # Скриване/показване на терминалния изход за GUI табовете
566 if tab_name == "terminal":
567 self.output_label.grid_remove()
568 self.output_text.grid_remove()
569 else:
570 self.output_label.grid()
571 self.output_text.grid()
572
573 # Актуализиране на бутоните
574 for name, btn in self.nav_buttons.items():
575 if name == tab_name:
576 btn.configure(fg_color=("gray75", "gray25"))
577 else:
578 btn.configure(fg_color=["#3B8ED0", "#1F6AA5"])
579
580 def run_command(self, command, success_msg="Операцията завърши успешно"):
581 """Изпълнява winget команда в отделна нишка"""
582 def execute():
583 self.update_status("🔄 Изпълнява се...")
584 self.output_text.delete("1.0", "end")
585 self.output_text.insert("1.0", f"$ {command}\n\n")
586
587 try:
588 process = subprocess.Popen(
589 command,
590 shell=True,
591 stdout=subprocess.PIPE,
592 stderr=subprocess.PIPE,
593 text=True,
594 encoding='utf-8',
595 errors='replace',
596 creationflags=subprocess.CREATE_NO_WINDOW
597 )
598
599 stdout, stderr = process.communicate()
600
601 output = stdout if stdout else stderr
602 self.output_text.insert("end", output)
603
604 if process.returncode == 0:
605 self.update_status(f"{success_msg}")
606 else:
607 self.update_status("❌ Грешка при изпълнение")
608
609 except Exception as e:
610 self.output_text.insert("end", f"\n❌ Грешка: {str(e)}")
611 self.update_status("❌ Грешка")
612
613 threading.Thread(target=execute, daemon=True).start()
614
615 def search_packages(self):
616 query = self.search_entry.get().strip()
617 if not query:
618 messagebox.showwarning("Внимание", "Моля, въведете име на пакет")
619 return
620 self.run_command(f'winget search "{query}"', "Търсенето завърши")
621
622 def install_package(self):
623 pkg_id = self.install_entry.get().strip()
624 if not pkg_id:
625 messagebox.showwarning("Внимание", "Моля, въведете ID на пакет")
626 return
627 self.run_command(
628 f'winget install --id {pkg_id} -e --silent --accept-package-agreements --accept-source-agreements',
629 f"Пакетът {pkg_id} е инсталиран"
630 )
631
632 def upgrade_all(self):
633 self.run_command(
634 'winget upgrade --all --silent --include-unknown --accept-package-agreements',
635 "Всички пакети са обновени"
636 )
637
638 def upgrade_package(self):
639 pkg_id = self.upgrade_entry.get().strip()
640 if not pkg_id:
641 messagebox.showwarning("Внимание", "Моля, въведете ID на пакет")
642 return
643 self.run_command(
644 f'winget upgrade --id {pkg_id} -e --silent --accept-package-agreements',
645 f"Пакетът {pkg_id} е обновен"
646 )
647
648 def uninstall_package(self):
649 pkg_id = self.uninstall_entry.get().strip()
650 if not pkg_id:
651 messagebox.showwarning("Внимание", "Моля, въведете ID на пакет")
652 return
653
654 if messagebox.askyesno("Потвърждение",
655 f"Сигурни ли сте, че искате да деинсталирате {pkg_id}?"):
656 self.run_command(
657 f'winget uninstall --id {pkg_id} -e',
658 f"Пакетът {pkg_id} е деинсталиран"
659 )
660
661 def list_packages(self):
662 self.run_command('winget list', "Списъкът е зареден")
663
664 def filter_packages(self):
665 filter_text = self.filter_entry.get().strip()
666 if not filter_text:
667 messagebox.showwarning("Внимание", "Моля, въведете текст за филтриране")
668 return
669 self.run_command(f'winget list | findstr /i "{filter_text}"', "Филтрирането завърши")
670
671 def show_info(self):
672 pkg_id = self.info_entry.get().strip()
673 if not pkg_id:
674 messagebox.showwarning("Внимание", "Моля, въведете ID на пакет")
675 return
676 self.run_command(f'winget show --id {pkg_id}', "Информацията е заредена")
677
678 def clear_output(self):
679 self.output_text.delete("1.0", "end")
680 self.update_status("✅ Изходът е изчистен")
681
682 def update_status(self, text):
683 """Актуализира статус бара"""
684 self.status_label.configure(text=text)
685
686if __name__ == "__main__":
687 app = WingetGUI()
688 app.mainloop()