from PySide2 import QtCore, QtWidgets, QtGui
import sys
import time

class DownloadThread(QtCore.QObject):
    finished = QtCore.Signal(str)
    error = QtCore.Signal(str)
    progress = QtCore.Signal(int)
    status = QtCore.Signal(str)
    
    def __init__(self):
        super(DownloadThread, self).__init__()
        
    def run(self):
        self.status.emit("Downloading...")
        
        # Simulate progress updates
        for i in range(0, 101, 10):
            self.progress.emit(i)
            time.sleep(0.5)  # Simulate work
        
        self.finished.emit("Download completed!")

class TestWindow(QtWidgets.QWidget):
    def __init__(self):
        super(TestWindow, self).__init__()

        self.setWindowTitle("Cool Thread Demo")
        self.setMinimumWidth(500)
        self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
        self.create_widgets()
        self.create_layouts()
        self.create_connections()

    def create_widgets(self):
        self.start_btn = QtWidgets.QPushButton("Start Download")
        self.cancel_btn = QtWidgets.QPushButton("Cancel")
        self.progress_bar = QtWidgets.QProgressBar()
        self.progress_bar.setMinimum(0)
        self.progress_bar.setMaximum(100)
        self.progress_bar.setTextVisible(True)
        self.progress_bar.setFormat("%p%")
        self.status_label = QtWidgets.QLabel("Ready")
        
    def create_layouts(self):
        button_layout = QtWidgets.QHBoxLayout()
        button_layout.addWidget(self.start_btn)
        button_layout.addWidget(self.cancel_btn)

        main_layout = QtWidgets.QVBoxLayout(self)
        main_layout.addLayout(button_layout)
        main_layout.addWidget(self.progress_bar)
        main_layout.addWidget(self.status_label)

    def create_connections(self):
        self.cancel_btn.clicked.connect(self.close)
        self.start_btn.clicked.connect(self.start_download)
        
    def start_download(self):
        # Create the worker
        self.download_worker = DownloadThread()
        
        # Connect signals from the worker
        self.download_worker.progress.connect(self.update_progress)
        self.download_worker.status.connect(self.update_status)
        self.download_worker.finished.connect(self.download_finished)
        
        # Create a QThread
        self.thread = QtCore.QThread()
        
        # Move worker to the thread
        self.download_worker.moveToThread(self.thread)
        
        # Connect thread start signal to worker's run method
        self.thread.started.connect(self.download_worker.run)
        
        # When worker finishes, quit the thread
        self.download_worker.finished.connect(self.thread.quit)
        
        # Disable the start button while downloading
        self.start_btn.setEnabled(False)
        
        # Start the thread
        self.thread.start()

    def update_progress(self, value):
        self.progress_bar.setValue(value)
        
    def update_status(self, message):
        self.status_label.setText(message)
        
    def download_finished(self, message):
        self.status_label.setText(message)
        self.start_btn.setEnabled(True)

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    app.setStyle(QtWidgets.QStyleFactory.create("fusion"))

    win = TestWindow()
    win.show()

    app.exec_()