1

Basically I need to run two while loops at the same time. The reason being that I need one loop to update the GUI, and the other to check if the program is connected to the internet. So maybe this requires multi-threading, or maybe I am just one webpage away to fixing my problem. Here's my source code:

# -*- coding: utf-8 -*-

import sys
import urllib2
from Tkinter import *
import time
import socket

def TheMainProgram():
    airid = 'http://www.aviationweather.gov/metar/data?ids={airid}&format=raw&hours=0&taf=off&layout=off&date=0'.format(airid=e1.get())
    website = urllib2.urlopen(airid)
    website_html = website.read()
    data_start = website_html.find("<!-- Data starts here -->")
    br1 = data_start + 25
    br2 = website_html.find("<br />")
    metar_slice = website_html[br1:br2]
    print("Here is the undecoded METAR data:\n"+metar_slice)
    root2 = Tk()
    root2.title("#Conection_Made#")
    metar_dat_label = Label(root2, text="Here is the undecoded METAR data:")
    metar_dat_label_ln_2 = Label(root2, text=metar_slice)
    metar_dat_label.grid(row=0)
    metar_dat_label_ln_2.grid(row=1)    


def _quit():
    sys.exit()

def internet(host="8.8.8.8", port=53, timeout=3):
    try:
        socket.setdefaulttimeout(timeout)
        socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port))
        return True
    except Exception:
        return False


def tkupdate():
    while True:
        root1.update()


def internet_loop():
    while True:
        out = internet()
        if out == True:
            connetion2internet.configure(text="YOU ARE CONNECTED TO THE INTERNET", fg="green")
        if out == False:
            connetion2internet.configure(text="YOU ARE NOT CONNECTED TO THE INTERNET", fg="red")


root1 = Tk()
root1.title("Welcome")
warning = Label(root1, text="*********** WARNING REQURIES INTERET TO RUN ***********")
warning.grid(row=0)
connetion2internet = Label(root1, text="")
connetion2internet.grid(row=1)
airport_code = Label(root1,text="Enter Airport Code:")
airport_code.grid(row=2, sticky="W")
e1 = Entry(root1)
e1.grid(row=2, sticky="E")
button1 = Button(root1, text="Contunue", command=daMainProgram).grid(row=3, sticky="W")
button2 = Button(root1, text="Quit", command=_quit)
button2.grid(row=3, sticky="E")
tkupdate()
internet_loop()
Mr.Zeus
  • 424
  • 8
  • 25
  • 1
    Your `tkupdate` function is, in essence, what Tkinters `mainloop` is for. You should look into using the mainloop, and how you can check for an internet connection periodically using the `after` method. – SneakyTurtle Aug 27 '17 at 21:44
  • Yes I do understand and I usually do use the mainloop, but in this code I wanted to have the same control over the tkupdate as the internet_loop and if you can give an answer please answer it rather than commenting – Mr.Zeus Aug 27 '17 at 21:48
  • When you're using a GUI library, there really should only ever be **one** main loop. However, many libraries provide you with ways to run code as if it were part of the main loop. I haven't done Tkinter in a while, but see [_How do you run your own code alongside Tkinter's event loop?_](https://stackoverflow.com/questions/459083/how-do-you-run-your-own-code-alongside-tkinters-event-loop) . That should give you an idea of what you need to do. – Christian Dean Aug 27 '17 at 21:52
  • Thank you for answering! But please don't comment and just answer it(not in a rude way) – Mr.Zeus Aug 27 '17 at 21:56
  • @Mr.Zeus No offense taken. However, I'm afraid I cannot answer this question because it is a duplicate of the question I linked to in the above comment. – Christian Dean Aug 27 '17 at 22:13
  • 1
    Possible duplicate of [How do you run your own code alongside Tkinter's event loop?](https://stackoverflow.com/questions/459083/how-do-you-run-your-own-code-alongside-tkinters-event-loop) – Christian Dean Aug 27 '17 at 22:13

1 Answers1

6

How about something like the following. Spawn two processes. Each one runs in parallel and the target functions can be replaced with your own.

from multiprocessing import Process
from time import sleep

def func1():
    while True:
        print("func1 up and running")
        sleep(1)

def func2():
    while True:
        print("func2 up and running")
        sleep(1)


if __name__ == '__main__':

    proc1 = Process(target=func1)
    proc1.start()

    proc2 = Process(target=func2)
    proc2.start()

The output is:

func1 up and running
func2 up and running
func1 up and running
func2 up and running
func1 up and running
func2 up and running
func1 up and running
func2 up and running
...
Dewald Abrie
  • 1,392
  • 9
  • 21
  • For some reason I tried this using your code and also on another project and it worked but when I came around to the project I asked about I got this error: – Mr.Zeus Aug 28 '17 at 13:44
  • The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec(). Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__() to debug.(this is repeated 3 more times) Tcl_ServiceModeHook: Notifier not initialized – Mr.Zeus Aug 28 '17 at 13:51
  • @Mr.Zeus You probably only want to spawn one extra process (the one monitoring the internet connection) while running your main application in the already existing main process. In order to get information from your internet-checking process you might have to use some shared memory which you can periodically check from your main loop for updates. See docs: https://docs.python.org/2/library/multiprocessing.html#multiprocessing.Value – Dewald Abrie Aug 29 '17 at 00:58
  • 1
    This is the best example of code to spawn processes for functions. It has just allowed me to speed up my code by a mile. – Alby Feb 07 '21 at 03:24