'while True Loop keeps killing python
It is very possible that this issue has been asnwered often, but Google didnt help me so far, so I am posting it myself. I just started a new little Project where I want to make a chat for my school server. I am using wxpython for the UI. To keep the Chat updated I use a while True Loop, but it keeps killing python and i cant put in any more words. Currently the broken Code is marked with hashtags. You can put Anything in the binary part, as its not coded yet.This is what the chat should look like.This is how it looks with the while True Loop "working". Note: All the things, that are still in German on the Screenshots have been changed to English in the Code posted
import wx
import sys
import getpass
class MainClass(wx.Frame):
def __init__(self, parent, title, size, colour):
super(MainClass, self).__init__(parent, title = title, size = (size))
panel = wx.Panel(self)
self.chat = wx.TextCtrl(panel,pos=(0,0), size=(1920,975),style =wx.TE_MULTILINE|wx.TE_READONLY)
self.input = wx.TextCtrl(panel, pos=(0, 975),size=(1820,50))
self.input.SetHint("write your Message here")
Senden = wx.Button(panel, label='send Message',pos=(1820,975),size=(100,50))
Senden.Bind(wx.EVT_BUTTON, self.on_press)
sys.stdout=RedirectText(self.chat)
self.SetBackgroundColour(colour)
self.Show()
written = ""
try:
with open(NameTxt, "r") as txt:
data = txt.read()
print(data)
except IOError:
print("!!!.txt-Data not found!!!")
#while True:
# with open(NameTxt, "r") as txt:
# data = txt.read()
# if data != written:
# hold = data
# data.replace(written,"")
# print(data)
# written =hold
#time.sleep(3)
def on_press(self, event):
value = self.input.GetValue()
username = str(getpass.getuser())
message = username+': '+value
print(message)
try:
with open(NameTxt, "a") as f:
f.write("\n"+message)
self.input.Clear()
except IOError:
print("!!!.txt-Data not found!!!")
class RedirectText:
def __init__(self,aWxTextCtrl):
self.out=aWxTextCtrl
def write(self,text):
self.out.WriteText(text)
class ChatStart(wx.Frame):
def __init__(self, parent, title, size):
super(ChatStart, self).__init__(parent, title = title, size = (size))
startPanel = wx.Panel(self)
self.BinKeyInput = wx.TextCtrl(startPanel, pos=(0, 0),size=(600,50))
self.BinKeyInput.SetHint("Paste your BinaryKey here")
self.TxtNameInput = wx.TextCtrl(startPanel, pos=(0, 50),size=(600,50))
self.TxtNameInput.SetHint("Put the Name of the .txt Data here")
self.Start = wx.Button(startPanel, label='start Chat',pos=(150,100),size=(300,50))
self.Show()
self.Start.Bind(wx.EVT_BUTTON, self.lesen)
def lesen(self, event):
global NameTxt
global BinKey
BinKey=self.BinKeyInput.GetValue()
NameTxt=self.TxtNameInput.GetValue()
self.Close()
MainClass(None, title='!Chat', size=(1920,1080), colour = 'black')
app = wx.App()
ChatStart(None, size=(600,200), title = "Start Menu")
app.MainLoop()
A possible input for the first Menu
EDIT: The use of this program is intended as follows: multiple users can chat using a binary key and a Chat name for safety, cause school. Now I want to be able to detect when another person posts something in the chat so it pops up at my screen aswell when we both launch the programm on seperate PCs connected via a school network server. My logic was that an infinite loop will continuously check, if there are new messages. I didn't expect to kill python, but I did expect to run into issues with the input box and the button. I hope that helps
Solution 1:[1]
What you are missing is the fact that once the loop is running, you never revisit the wx.App mainloop. In effect you freeze the GUI while processing the file, for ever.Yield reverts control, momentarily, back to the mainloop, making it responsive again.
import wx
import sys
import getpass
import time
class MainClass(wx.Frame):
def __init__(self, parent, title, size, colour):
super(MainClass, self).__init__(parent, title = title, size = (size))
panel = wx.Panel(self)
self.chat = wx.TextCtrl(panel,pos=(0,0), size=(820,475),style =wx.TE_MULTILINE|wx.TE_READONLY)
self.input = wx.TextCtrl(panel, pos=(0, 475),size=(820,50), style=wx.TE_PROCESS_ENTER)
self.input.SetHint("write your Message here")
Senden = wx.Button(panel, label='send Message',pos=(825,475),size=(100,50))
Senden.Bind(wx.EVT_BUTTON, self.on_press)
self.input.Bind(wx.EVT_TEXT_ENTER, self.on_press)
self.Bind(wx.EVT_CLOSE, self.OnQuit)
sys.stdout=RedirectText(self.chat)
self.SetBackgroundColour(colour)
self.Show()
self.looping = True
# try:
# with open(NameTxt, "r") as txt:
# data = txt.read()
# print(data)
# except IOError:
# print("!!!.txt-Data not found!!!")
while self.looping:
with open(NameTxt, "r") as txt:
data = txt.read()
if data:
print(data)
with open(NameTxt, "w") as txt: # Clear file
pass
wx.GetApp().Yield()
time.sleep(0.5)
def on_press(self, event):
value = self.input.GetValue()
username = str(getpass.getuser())
message = username+': '+value
try:
with open(NameTxt, "a") as f:
f.write("\n"+message)
self.input.Clear()
except IOError:
print("!!!.txt-Data not found!!!")
def OnQuit(self, event):
self.looping = False
time.sleep(0.5)
self.Destroy()
class RedirectText:
def __init__(self,aWxTextCtrl):
self.out=aWxTextCtrl
def write(self,text):
self.out.WriteText(text)
class ChatStart(wx.Frame):
def __init__(self, parent, title, size):
super(ChatStart, self).__init__(parent, title = title, size = (size))
startPanel = wx.Panel(self)
self.BinKeyInput = wx.TextCtrl(startPanel, pos=(0, 0),size=(600,50))
self.BinKeyInput.SetHint("Paste your BinaryKey here")
self.TxtNameInput = wx.TextCtrl(startPanel, pos=(0, 50),size=(600,50))
self.TxtNameInput.SetHint("Put the Name of the .txt Data here")
self.Start = wx.Button(startPanel, label='start Chat',pos=(150,100),size=(300,50))
self.Show()
self.Start.Bind(wx.EVT_BUTTON, self.lesen)
self.Bind(wx.EVT_CLOSE, self.OnQuit)
def lesen(self, event):
global NameTxt
global BinKey
BinKey=self.BinKeyInput.GetValue()
NameTxt=self.TxtNameInput.GetValue()
chat = MainClass(self, title='!Chat', size=(950, 600), colour = 'black')
def OnQuit(self, event):
self.Destroy()
app = wx.App()
ChatStart(None, size=(600,200), title = "Start Menu")
app.MainLoop()
The self.looping variable is to enable a reasonable closing of the file, if exiting the program.
That said, using a file is fraught with issues and you may be better off using sockets or a database like sqlite3.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Rolf of Saxony |
