# cPy qt : varios ways of multi-tasking
# Copyright by Anthony Vogelaar, Perth Scotland
# rev 0.10  2026-04-02  initial release

import  subprocess;         subprocess.run('clear')
import  time, asyncio
from    PySide6.QtWidgets   import  QApplication, QWidget, QLabel, QPushButton
from    PySide6.QtCore      import  QTimer

# ========================== demo 1  ==============================

# No multi-tasking
class Gui1(QWidget):

    def __init__(self):
        app = QApplication()            # Qt framework
        super().__init__()              # instantiate QWidget = GUI
        self.resize(300, 130)
        self.n   = 0                    # number of times button pressed
        self.btn = QPushButton('Press Me', self)
        self.btn.setGeometry(75, 50, 150, 25)
        self.btn.clicked.connect(self.onBtnClick)
        self.show()
        app.exec()


    def onBtnClick(self, sts):
        self.n += 1
        self.btn.setText(f'I am pressed {self.n} times')


def demo1():
    print('demo No Qt multi-tasking')
    Gui1()


#demo1()

# ========================== demo 2  ==============================

# QTimer multi-tasking
class Gui2(QWidget):

    def __init__(self):
        app = QApplication()            # Qt framework
        super().__init__()              # instantiate QWidget = GUI
        self.resize(300, 130)
        self.n   = 0                    # number of times button pressed
        self.btn = QPushButton('Press Me', self)
        self.btn.setGeometry(75, 50, 150, 25)
        self.btn.clicked.connect(self.onBtnClick)
        tmr = QTimer()
        tmr.timeout.connect(self.onTimer)
        tmr.start(1000)                 # run @ 1 Hz
        self.show()
        app.exec()


    def onBtnClick(self, sts):
        self.n += 1
        self.btn.setText(f'I am pressed {self.n} times')


    def onTimer(self):
        print('*', end='', flush=True)


def demo2():
    print('demo Qt QTimer based multi-tasking')
    Gui2()


# demo2()

# ========================== demo 3  ==============================

# Cooperative multi-tasking
class Gui3(QWidget):

    def __init__(self):
        self.app = QApplication()       # Qt framework
        super().__init__()              # instantiate QWidget = GUI
        self.resize(300, 130)
        self.n   = 0                    # number of times button pressed
        self.btn = QPushButton('Press Me', self)
        self.btn.setGeometry(75, 50, 150, 25)
        self.btn.clicked.connect(self.onBtnClick)
        self.show()


    def onBtnClick(self, sts):
        self.n += 1
        self.btn.setText(f'I am pressed {self.n} times')


    # refresh Qt loop, call @ 20 Hz
    def refresh(self):
        self.app.processEvents()


def demo3():
    print('demo Qt cooperative multi-tasking')
    print('   terminate this application with Ctrl-C')
    gui = Gui3()
    while True:
        for _ in range(20):
            gui.refresh()
            time.sleep(0.05)
        print('*', end='', flush=True)


# demo3()

# ========================== demo 4  ==============================

# Cooperative multi-tasking
class Gui4(QWidget):

    def __init__(self):
        self.app = QApplication()       # Qt framework
        super().__init__()              # instantiate QWidget = GUI
        self.resize(300, 130)
        self.n   = 0                    # number of times button pressed
        self.btn = QPushButton('Press Me', self)
        self.btn.setGeometry(75, 50, 150, 25)
        self.btn.clicked.connect(self.onBtnClick)
        asyncio.create_task(self.taskRefresh())
        self.show()


    def onBtnClick(self, sts):
        self.n += 1
        self.btn.setText(f'I am pressed {self.n} times')


    # refresh Qt loop, call @ 20 Hz
    async def taskRefresh(self):
        while True:
            await asyncio.sleep(0.05)
            self.app.processEvents()


    def closeEvent(self, event):
        raise KeyboardInterrupt


async def demo4():
    print('demo Qt asyncio multi-tasking')
    gui = Gui4()
    while True:
        await asyncio.sleep(1)
        print('*', end='', flush=True)


try   : asyncio.run(demo4())
except: print('\nApplication terminated')

# ============================== end =============================
