Skip to content

Commit

Permalink
Merge pull request #11 from Teraskull/develop
Browse files Browse the repository at this point in the history
Update 1.5.0
  • Loading branch information
Teraskull authored Jun 11, 2020
2 parents 604d4b8 + 5870681 commit a2ce204
Show file tree
Hide file tree
Showing 29 changed files with 1,361 additions and 76 deletions.
11 changes: 4 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@

<div align="center">

![Main window screenshot](images/app_main.png)
![Main window screenshot](screenshots/app_main.png)

![Loading screenshot](images/app_loading.png)
![Loading screenshot](screenshots/app_loading.png)

![Confirmation screenshot](images/app_confirm.png)
![Confirmation screenshot](screenshots/app_confirm.png)

</div>

Expand All @@ -44,10 +44,7 @@

## App limitations:

* [FIXED] ~~It takes a few seconds to list all currently installed apps.~~
* [FIXED] ~~When uninstalling apps, PowerShell windows will open.~~
* You can only **uninstall** apps with this GUI, hence the name.
* You cannot uninstall other apps, for example Cortana, with this GUI, because PowerShell does not support it.
* You cannot uninstall other apps, for example Cortana or Edge. This GUI was designed to be simple and safe, so that you cannot break anything using it.
* App disk space is approximate and taken from Microsoft Store, there is no other way to get real-time app size.

## Dependencies:
Expand Down
87 changes: 72 additions & 15 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from PyQt5.QtWidgets import QApplication, QMessageBox
from PyQt5.QtCore import Qt, QThread, pyqtSignal
from PyQt5.QtGui import QCursor, QPixmap, QIcon
from gui_about import Ui_AboutWindow
from gui_main import Ui_MainWindow
from PyQt5.QtGui import QCursor
import webbrowser
import subprocess
import img_res
import sys


__version__ = "1.4.0"
__version__ = "1.5.0"


class Logic():
Expand Down Expand Up @@ -41,16 +42,24 @@ def __init__(self):
ui.checkBox_22: 16.62, ui.checkBox_23: 12.40, ui.checkBox_24: 30.59,
ui.checkBox_25: 35.02, ui.checkBox_26: 119.06, ui.checkBox_27: 64.59,
}
ui.progressbar.setValue(0)
ui.progressbar.setMaximum(len(self.checkbox_dict))
ui.actionRefresh.triggered.connect(self.app_refresh)
ui.actionHomepage.triggered.connect(self.app_homepage)
ui.actionAbout.triggered.connect(self.app_about)
ui.actionQuit.triggered.connect(self.app_quit)
ui.button_uninstall.clicked.connect(self.uninstall)
ui.button_select_all.clicked.connect(self.select_all)
ui.button_deselect_all.clicked.connect(self.deselect_all)
ui.refresh_btn.clicked.connect(self.app_refresh)
ui.refresh_bind.activated.connect(self.app_refresh)
ui.homepage_btn.clicked.connect(self.app_homepage)
ui.homepage_bind.activated.connect(self.app_homepage)
ui.about_btn.clicked.connect(self.app_about)
ui.about_bind.activated.connect(self.app_about)
ui.quit_btn.clicked.connect(self.app_quit)
ui.quit_bind.activated.connect(self.app_quit)
about.button_quit_about.clicked.connect(self.about_close)
for i in self.checkbox_dict:
i.clicked.connect(self.enable_buttons)
with open("style.css", 'r') as file:
i.setStyleSheet(file.read())

self.workerThread = QThread()
self.thread_list = []
Expand All @@ -68,7 +77,9 @@ def app_refresh(self):
i.setEnabled(False)
i.setChecked(False)
ui.progressbar.show()
ui.actionRefresh.setDisabled(True)
ui.refresh_btn.setDisabled(True)
ui.refresh_bind.setEnabled(False)
ui.refresh_btn.setIcon(QIcon(':/icon/no_refresh_icon.png'))
ui.button_select_all.setDisabled(True)
ui.button_deselect_all.setDisabled(True)
ui.button_uninstall.setDisabled(True)
Expand All @@ -82,7 +93,9 @@ def thread_finished(self):
ui.progressbar.setValue(0)
QApplication.setOverrideCursor(QCursor())
ui.label_info.setText('Select the default Windows 10 apps to uninstall (Hover over items to view description):')
ui.actionRefresh.setDisabled(False)
ui.refresh_btn.setDisabled(False)
ui.refresh_bind.setEnabled(True)
ui.refresh_btn.setIcon(QIcon(':/icon/refresh_icon.png'))
self.enable_buttons()

def enable_installed(self, i):
Expand All @@ -104,16 +117,22 @@ def enable_buttons(self):
ui.label_size.setText(f'{self.total_size:.2f} MB')
if any(i.isChecked() for i in self.installed_apps):
ui.button_uninstall.setDisabled(False)
ui.button_uninstall.setIcon(QIcon(':/icon/trash_icon.png'))
ui.button_deselect_all.setDisabled(False)
ui.button_deselect_all.setIcon(QIcon(':/icon/cancel_icon.png'))
else:
ui.button_deselect_all.setDisabled(True)
ui.button_uninstall.setDisabled(True)
ui.button_uninstall.setIcon(QIcon(':/icon/no_trash_icon.png'))
ui.button_deselect_all.setDisabled(True)
ui.button_deselect_all.setIcon(QIcon(':/icon/no_cancel_icon.png'))
ui.label_size.setText('0 MB')

if all(i.isChecked() for i in self.installed_apps):
ui.button_select_all.setDisabled(True)
ui.button_select_all.setIcon(QIcon(':/icon/no_check_icon.png'))
else:
ui.button_select_all.setDisabled(False)
ui.button_select_all.setIcon(QIcon(':/icon/check_icon.png'))

@staticmethod
def app_homepage():
Expand All @@ -124,10 +143,25 @@ def app_about():
about.setWindowModality(Qt.ApplicationModal)
about.show()

@staticmethod
def about_close():
about.close()

@staticmethod
def app_quit():
buttonReply = QMessageBox.question(ui, 'PyDebloatX', "Quit PyDebloatX?", QMessageBox.Yes | QMessageBox.No)
if buttonReply == QMessageBox.Yes:
pixmap = QPixmap('icon.ico').scaledToWidth(35, Qt.SmoothTransformation)
msg_quit = QMessageBox()
msg_quit.setText("Quit PyDebloatX?")
msg_quit.addButton(QMessageBox.Yes).setProperty('class', 'button_yes')
msg_quit.addButton(QMessageBox.No).setProperty('class', 'button_no')
msg_quit.setWindowFlags(Qt.Dialog | Qt.CustomizeWindowHint)
msg_quit.setWindowIcon(QIcon('icon.ico'))
msg_quit.setWindowTitle("PyDebloatX")
msg_quit.setIconPixmap(pixmap)
with open("style.css", 'r') as file:
msg_quit.setStyleSheet(file.read())
msg_quit_result = msg_quit.exec_()
if msg_quit_result == QMessageBox.Yes:
app.quit()

def select_all(self):
Expand All @@ -147,15 +181,38 @@ def uninstall(self):
for i in self.installed_apps:
if i.isChecked():
j += 1
buttonReply = QMessageBox.question(ui, 'PyDebloatX', f"Uninstall {j} app{'s' if j > 1 else ''}?\n\n{self.total_size:.2f} MB of of disk space will be available.", QMessageBox.Yes | QMessageBox.No)
if buttonReply == QMessageBox.Yes:
for i in self.installed_apps:
pixmap = QPixmap('icon.ico').scaledToWidth(35, Qt.SmoothTransformation)

msg_confirm = QMessageBox()
msg_confirm.setText(f"Uninstall {j} app{'s' if j > 1 else ''}?\n\n{self.total_size:.2f} MB of of disk space will be available.")
msg_confirm.addButton(QMessageBox.Yes).setProperty('class', 'button_yes')
msg_confirm.addButton(QMessageBox.No).setProperty('class', 'button_no')
msg_confirm.setWindowFlags(Qt.Dialog | Qt.CustomizeWindowHint)
msg_confirm.setWindowIcon(QIcon('icon.ico'))
msg_confirm.setWindowTitle("PyDebloatX")
msg_confirm.setIconPixmap(pixmap)
with open("style.css", 'r') as file:
msg_confirm.setStyleSheet(file.read())
msg_confirm_result = msg_confirm.exec_()

if msg_confirm_result == QMessageBox.Yes:
for i in self.checkbox_dict:
if i.isChecked():
subprocess.Popen(["powershell", f"(Get-AppxPackage {self.checkbox_dict[i]} | Remove-AppxPackage)"], shell=True)
i.setChecked(False)
i.setEnabled(False)
self.installed_apps.remove(i)
self.deselect_all()
QMessageBox.information(ui, 'PyDebloatX', f"Uninstalling {j} app{'s' if j > 1 else ''}.", QMessageBox.Ok)

msg_proceed = QMessageBox()
msg_proceed.setText(f"Uninstalling {j} app{'s' if j > 1 else ''}.")
msg_proceed.addButton(QMessageBox.Ok).setProperty('class', 'button_yes')
msg_proceed.setWindowFlags(Qt.Dialog | Qt.CustomizeWindowHint)
msg_proceed.setWindowTitle("PyDebloatX")
msg_proceed.setIconPixmap(pixmap)
with open("style.css", 'r') as file:
msg_proceed.setStyleSheet(file.read())
msg_proceed.exec_()


class CheckApps(QThread):
Expand Down
20 changes: 15 additions & 5 deletions gui_about.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
# -*- coding: utf-8 -*-
from PyQt5.QtWidgets import QMainWindow, QWidget, QLabel, QVBoxLayout, QPushButton
from PyQt5.QtCore import Qt, QRect, QCoreApplication, QMetaObject
from PyQt5.QtWidgets import QMainWindow, QWidget, QLabel, QVBoxLayout
from PyQt5.QtGui import QIcon, QFont, QPixmap


class Ui_AboutWindow(QMainWindow):
def __init__(self):
super(Ui_AboutWindow, self).__init__()
self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.WindowCloseButtonHint)
self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.CustomizeWindowHint)
self.setWindowIcon(QIcon('icon.ico'))
self.setFixedSize(240, 150)
self.setFixedSize(241, 190)

def setupUi(self):
self.centralwidget = QWidget(self)
with open("style.css", 'r') as file:
self.centralwidget.setStyleSheet(file.read())
self.verticalLayoutWidget = QWidget(self.centralwidget)
self.verticalLayoutWidget.setGeometry(QRect(10, 10, 221, 81))
self.verticalLayout = QVBoxLayout(self.verticalLayoutWidget)
Expand All @@ -36,7 +38,7 @@ def setupUi(self):
self.label_version.setLayoutDirection(Qt.LeftToRight)
self.verticalLayout.addWidget(self.label_version, 0, Qt.AlignHCenter)
self.verticalLayoutWidget_2 = QWidget(self.centralwidget)
self.verticalLayoutWidget_2.setGeometry(QRect(10, 100, 221, 41))
self.verticalLayoutWidget_2.setGeometry(QRect(10, 100, 221, 81))
self.verticalLayout_2 = QVBoxLayout(self.verticalLayoutWidget_2)
self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
self.label_copyright = QLabel(self.verticalLayoutWidget_2)
Expand All @@ -51,8 +53,15 @@ def setupUi(self):
self.label_author.setFont(font)
self.label_author.setLayoutDirection(Qt.LeftToRight)
self.verticalLayout_2.addWidget(self.label_author, 0, Qt.AlignHCenter)
self.setCentralWidget(self.centralwidget)
self.button_quit_about = QPushButton(self.verticalLayoutWidget_2)
self.verticalLayout_2.addWidget(self.button_quit_about)
self.button_quit_about.setMinimumSize(100, 30)
self.button_quit_about.setProperty('class', 'Aqua')

with open("style.css", 'r') as file:
self.button_quit_about.setStyleSheet(file.read())

self.setCentralWidget(self.centralwidget)
self.retranslateUi()
QMetaObject.connectSlotsByName(self)

Expand All @@ -63,3 +72,4 @@ def retranslateUi(self):
self.label_version.setText(_translate("MainWindow", ""))
self.label_copyright.setText(_translate("MainWindow", "Copyright © 2020 by"))
self.label_author.setText(_translate("MainWindow", "Anton Grouchtchak."))
self.button_quit_about.setText(_translate("MainWindow", "OK"))
Loading

0 comments on commit a2ce204

Please sign in to comment.