最終更新 1 month ago

urocibg revised this gist 1 month ago. Go to revision

2 files changed, 688 insertions

winget.png(file created)

Binary file changes are not shown

winget_gui.py(file created)

@@ -0,0 +1,688 @@
1 + """
2 + Winget Manager GUI - Пълно функционално приложение
3 + Изисквания: pip install customtkinter
4 + """
5 +
6 + import customtkinter as ctk
7 + import subprocess
8 + import threading
9 + from tkinter import messagebox
10 + import sys
11 +
12 + class 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 +
686 + if __name__ == "__main__":
687 + app = WingetGUI()
688 + app.mainloop()
Newer Older