Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

Why is there no response?

When our code is running in the background, the CPU will be preempted, and our window will stop refreshing and become unresponsive, and the operating system will assume that our program has stopped. But what if our program takes some time? The official documentation suggests that we use a single main thread to daemon our GUI programs, specifically to make our GUI programs a separate thread, so that the GUI can continue to hog CPU and this problem will be solved.

How do you do that?

Following the previous article, we planned to write the speed measurement steps as separate methods, call them in the main method start, and then execute the main method start in a GUI event loop by starting a thread (set this thread as a daemon thread) so that both our non-response and real-time refresh functions could be taken care of.

code

# -*- coding: utf-8 -*-
import PySimpleGUI as sg
from speedtest_cli import Speedtest
import threading

# instantiate the speed object
spt = Speedtest()

# Set the theme
sg.theme('BlueMono')

# Layout elements
one_line = [sg.Text('Best Server:'),sg.Text(size=(50.1),key='-BSTS-')]
two_line = [sg.Text('Download Speed:'),sg.Text(size=(50.1),key='-DLS-')]
three_line = [sg.Text('Upload speed:'),sg.Text(size=(50.1),key='-UPS-')]
four_line = [sg.Button('Start testing'),sg.Button('exit')]
five_line = [sg.Text(size=(50.1),key='-INFO-')]

# layout
layout = [
    one_line,
    two_line,
    three_line,
    four_line,
    five_line
]

def get_best_server(window) :
    window['-INFO-'].update('Start getting servers... ',text_color='red')
    res = spt.best.get('sponsor')
    print(res)
    window['-BSTS-'].update(res,text_color='yellow')

def get_download_speed(window) :
    window['-INFO-'].update('Start getting tested download rates... ',text_color='red')
    dSp1=spt.download()
    dSp=f'{dSp1/1024/1024:2.f} Mb/s'
    window['-DLS-'].update(dSp,text_color='yellow')

def get_upload_speed(window) :
    window['-INFO-'].update('Start getting test upload rate... ',text_color='red')
    uSp1=spt.upload()
    uSp=f'{uSp1/1024/1024:2.f} Mb/s'
    window['-UPS-'].update(uSp,text_color='yellow')

def end(window) :
    window['-INFO-'].update('Tests completed... ',text_color='red')

def start(window) :
    get_best_server(window)
    get_download_speed(window)
    get_upload_speed(window)
    end()

Create window
window = sg.Window('Speed Test Kit', layout)

# Event loop
while True:

    event, values = window.read(timeout=100)
    if event in (sg.WIN_CLOSED, 'exit') :# The user closes the window or clicks exit to exit
        break

    if event == 'Start testing':
        # to solve due to code execution window did not respond to questions, using threading (guardian mode)
        t1 = threading.Thread(target=start,daemon=True,args=[window])
        t1.start()

        print(f'Event: {event}')
        print(str(values))

window.close()
Copy the code

The effect

At this point, the problem is solved

Tip

  • Themes should be set before layout
  • Use daemon threads to resolve non-response issues
  • The business logic is choreographed in the main method

That’s all for today, thank you for reading, and we’ll see you next time.