Search code examples
kivyexport-to-excelopenpyxl

Use Kivy app while excel file is being built


So I am trying to create a Kivy app that allows a user to control and monitor various hardware components. Part of the code builds and continuously updates an Excel worksheet that imports temperature readings from the hardware's comm port, along with a time-stamp. I have been able to implement all of this so far, but I am unable to interact with the Kivy app while the Excel worksheet is being built/updated (i.e. while my hardware test is underway), and leaves me unable to use the app's features while the test is running (Such as the 'Pause' or 'Abort' buttons) until the worksheet is no longer being altered. So my question is: Is it possible to export to an Excel file while being able to simultaneously use the Kivy app? And if so, how?

This is part of my code that sets up the Excel worksheet. Thank you in advance!

from kivy.app import App
from openpyxl import Workbook, load_workbook
import time

class HomeScreen(Screen):
    def build(self):
        return HomeScreen()

    def RunExcelFile(self):
        wb = Workbook()
        ws = wb.active
        a = 0
        i = 2
        while (a < 5):
            ws.cell('A1').value = 'Time'
            ws.cell('B1').value = 'Batch 1'
            ws.cell('C1').value = 'Batch 2'
            column = 'A'
            row = i
            time_cell = column + str(row)
            t = time.localtime()
            ws.cell(time_cell).value = time.asctime(t)
            a = (a + 1)
            i = (i + 1)
            time.sleep(1)
        wb.save("scatter.xlsx")

Solution

  • If you are doing some background job without touching widgets or properties, you can use threading module without problems. Otherwise, you would need to use @mainthread decorator or Clock.

    import time
    import threading
    
    
    class HomeScreen(Screen):
    
        def run_excel_file(self):
    
            def job():
                for i in xrange(5):
                    print i
                    time.sleep(1)
                print 'job done'
    
            threading.Thread(target=job).start()