Posts: 73
Threads: 42
Joined: Jun 2017
Aug-24-2017, 10:09 PM
(This post was last modified: Aug-24-2017, 10:44 PM by ian.)
I create a wxPython Window app with a 1-second timer displaying clock on status bar, and a 5-minute timer running a function called Update1 every 5 minutes to download data and update a wx.Grid. I also add time.sleep in different places as need.
When using a single Thread to run Update1 every 5 minutes, it crashes during update, saying 'Not responding..'.
Will timer or sleep cause the crash? any solution? Thanks.
Posts: 12,038
Threads: 487
Joined: Sep 2016
In order to answer this question properly, we will need to see the code that crashed, along with the full error traceback.
I doubt that it was caused by the time or sleep routine.
Posts: 7,324
Threads: 123
Joined: Sep 2016
(Aug-24-2017, 10:09 PM)ian Wrote: I also add time.sleep in different places as need. Using time.sleep() will block the main loop of GUI.
use a wx.Timer() it run in own event loop that is non-blocking.
Timer demo blog,and doc.
Posts: 12,038
Threads: 487
Joined: Sep 2016
Posts: 73
Threads: 42
Joined: Jun 2017
Aug-27-2017, 02:59 PM
(This post was last modified: Aug-27-2017, 02:59 PM by ian.)
I spent 2 days to try on Windows 7 / 10 and x64 / x32; cut the code to minimum and remove all calls to timer & sleep but still crash with stop message (Not Responding) "Python has stopped working. A problem caused the program to stop working correctly. Windows will close the program and notify you if a solution is available." when not calling the thread, it seems ok. since the function code is kind of long. Let me know if need, I will post. I use python 3.6.2. Thanks.
import wx
import wx.grid
import pandas as pd
import googlefinance.client as gf
from threading import *
class RunThread(Thread):
def __init__(self, event, win):
Thread.__init__(self)
self.stopped = event
self.start()
def run(self):
print('Loading 0,0 ..')
#win.Update_5M(0, 0)
while True:
print('Loading 1,12 ..')
#win.Update_5M(1, 12)
self.stopped.wait(20)
class Frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Thread Crash", size=(530, 742), pos = (500, 100))
wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(sizer)
self.grid = self.Create_Grid()
stopFlag = Event()
RunThread(stopFlag, self)
def Update_5M(self, n, m):
self.dfg, self.dfr = self.Load_Data_Frame(n)
self.Update_Grid(self.dfr, self.grid, 'red', m)
self.Update_Grid(self.dfg, self.grid, 'green', m)
def Create_Grid(self):
self.colno = 11
self.colsz = [43,40,22,40,44,60,40,40,40,40,40]
grid = wx.grid.Grid(self, size=(522, 700), pos=(0,0))
grid.CreateGrid(1,11)
grid.SetRowLabelSize(60)
grid.SetLabelFont(wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.NORMAL))
grid.SetDefaultCellAlignment(wx.ALIGN_RIGHT,wx.ALIGN_CENTRE)
for col in range(self.colno):
grid.SetColSize(col,self.colsz[col])
return grid
if __name__ == "__main__":
app = wx.App()
win = Frame()
win.Show()
app.MainLoop()
Posts: 12,038
Threads: 487
Joined: Sep 2016
Aug-27-2017, 05:06 PM
(This post was last modified: Aug-27-2017, 05:06 PM by Larz60+.)
It seems to be working to a point for me.
I run windows 7 pro
python 3.6.2
wxpython phoenix 4.0.0b1
output:
Output: starting Frame
Starting thread
Loading 0,0 ..
Loading 1,12 ..
Loading 1,12 ..
I added the print statements.
Phoenix version??
Posts: 73
Threads: 42
Joined: Jun 2017
Yes, It works for me too because I commented out the functions (win.Update_5M) that crash. I added the functions back as below. Please let me know if it crashes or not on your machine. I use python 3.6.2 64bit with wxPython-4.0.0a3-cp36-cp36m-win_amd64.whl. win.Update_5M will run 1+ minutes before loading data in the grid.
import wx
import wx.grid
import pandas as pd
import googlefinance.client as gf
from threading import *
class RunThread(Thread):
def __init__(self, event, win):
Thread.__init__(self)
self.stopped = event
self.start()
def run(self):
print('Loading 0,0 ..')
win.Update_5M(0, 0)
while True:
print('Loading 1,12 ..')
win.Update_5M(1, 12)
self.stopped.wait(20)
class Frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Thread Crash", size=(530, 742), pos = (500, 100))
wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(sizer)
self.grid = self.Create_Grid()
stopFlag = Event()
RunThread(stopFlag, self)
def Update_5M(self, n, m):
self.dfg, self.dfr = self.Load_Data_Frame(n)
self.Update_Grid(self.dfr, self.grid, 'red', m)
self.Update_Grid(self.dfg, self.grid, 'green', m)
def Create_Grid(self):
self.colno = 11
self.colsz = [43,40,22,40,44,60,40,40,40,40,40]
grid = wx.grid.Grid(self, size=(522, 700), pos=(0,0))
grid.CreateGrid(1,11)
grid.SetRowLabelSize(60)
grid.SetLabelFont(wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.NORMAL))
grid.SetDefaultCellAlignment(wx.ALIGN_RIGHT,wx.ALIGN_CENTRE)
for col in range(self.colno):
grid.SetColSize(col,self.colsz[col])
return grid
def Update_Grid(self, df_head, grid, gor, n):
cols = grid.GetNumberCols()
rows = grid.GetNumberRows()
rl = []
for r in range(rows): rl.append(grid.GetRowLabelValue(r+n))
for row in range(len(df_head.index)):
r = row + n
grid.InsertRows(r,1,False)
param = {'q': df_head.values[row, 0],'i': "86400",'x': "TSE",'p': "5d"}
df = gf.get_price_data(param).tail(1)
o = 0
if len(df) < 1:
grid.DeleteRows(r,1,False)
r -= 1
o += 1
continue
PP = (df.values[0,1] + df.values[0,2] + df.values[0,3]) / 3
for col in range(self.colno):
if col != 2:
if n == 0:
if gor == 'green': grid.SetCellBackgroundColour(r, col, wx.Colour(row*50,200,row*40))
if gor == 'red': grid.SetCellBackgroundColour(r, col, wx.Colour(200,row*50,row*40))
else:
if gor == 'green': grid.SetCellBackgroundColour(r, col, wx.Colour(row*50,255,row*40))
if gor == 'red': grid.SetCellBackgroundColour(r, col, wx.Colour(255,row*50,row*40))
if col == 2: d = ('%.0f' %df_head.values[row, col])
elif col == 0: d = df_head.values[row, col]
elif col == 5: d = format(df_head.values[row, col], "8,d")
elif col < 6: d = ('%.2f' %df_head.values[row, col])
elif col == 6: d = '%.2f' %(PP + df.values[0,1] - df.values[0,2])
elif col == 7: d = '%.2f' %(PP * 2 - df.values[0,2])
elif col == 8: d = '%.2f' %PP
elif col == 9: d = '%.2f' %(PP * 2 - df.values[0,1])
elif col == 10: d = '%.2f' %(PP - df.values[0,1] + df.values[0,2])
grid.SetCellValue(r, col, d)
for r in range(len(rl)): grid.SetRowLabelValue(r+n+6-o,rl[r])
def Load_Data_Frame(self, n):
df_all = []
p = [['86400', '3M'], ['300', '2d']]
symb = pd.DataFrame(pd.read_csv('TSE.csv'))
for s in symb['Symbol']:
param = {'q': s,'i': p[n][0],'x': "TSE",'p': p[n][1]}
df = gf.get_price_data(param)
df['T'] = s
df['HiLo'] = 100 * (df['Close'] - df['Open']) / df['Open']
df['GoR'] = df['Close'] > df['Open']
df_all.append(df)
dfg = pd.DataFrame()
dfr = pd.DataFrame()
num = len(df_all)
for s in range(num):
i = len(df_all[s].index) - 1
if i < 10: continue
nGreen, nRed, vGreen, vRed = 0,0,0,0
hGreen, hRed, iGreen, iRed = 0,0,True,True
while iGreen or iRed:
if iGreen:
if df_all[s].values[i, 7]:
nGreen += 1
if hGreen < df_all[s].values[i, 6]:
hGreen = df_all[s].values[i, 6]
else: iGreen = False
if iRed:
if not df_all[s].values[i, 7]:
nRed += 1
if hRed > df_all[s].values[i, 6]:
hRed = df_all[s].values[i, 6]
else: iRed = False
i -= 1
if i < 0: break
vAvg20 = pd.Series(df_all[s]['Volume']).rolling(window=20).mean()
df_all[s]['U'] = round(hGreen, 2)
df_all[s]['D'] = round(-hRed, 2)
df_all[s]['gBars'] = int(nGreen)
df_all[s]['rBars'] = int(nRed)
df_all[s]['Vg'] = vGreen / vAvg20
df_all[s]['Vr'] = vRed / vAvg20
dUp = df_all[s][['T','Close','gBars','U','Vg','Volume']]
dDn = df_all[s][['T','Close','rBars','D','Vr','Volume']]
if dfg.empty: dfg = dUp.tail(1)
else: dfg = dfg.append(dUp.tail(1))
if dfr.empty: dfr = dDn.tail(1)
else: dfr = dfr.append(dDn.tail(1))
dfg6 = dfg.sort_values('gBars', ascending=False).head(6)
dfr6 = dfr.sort_values('rBars', ascending=False).head(6)
return dfg6, dfr6
if __name__ == "__main__":
app = wx.App()
win = Frame()
win.Show()
app.MainLoop()
Posts: 73
Threads: 42
Joined: Jun 2017
Aug-28-2017, 12:09 AM
(This post was last modified: Aug-28-2017, 12:23 PM by metulburr.)
This code needs TSE.csv as input containing the flowing:
CAE
HBC
YRI
OSB
WN
WFT
WCP
WCN
VSN
VII
TOU
REI.UN
PWF
PSK
PPL
POT
POW
PEY
PD
MRU
KXS
MEG
KEY
K
IMO
IPL
IMG
IFC
ALA
AQN
ARX
ATD.B
BAM.A
BB
BCE
BIR
BMO
BNS
CIX
CM
CNQ
CNR
CP
CTC.A
CVE
CWB
DGC
DOL
ELD
EMA
EMP.A
ENB
FR
FTS
GIB.A
GIL
GWO
H
HR.UN
IAG
HSE
L
LNR
LUN
MFC
MG
MX
QSR
RCI.B
RY
SAP
SHOP
SJR.B
SLF
SNC
SU
T
TD
THO
TRI
TRP
TXG
VET
VRX
AC
AGI
AGU
BTE
BTO
CCO
ERF
FM
NA
ECA
FNV
WPM
FTT
G
AEM
CPG
ABX
EFN
NFI
TECK.B
HBM
Posts: 12,038
Threads: 487
Joined: Sep 2016
Aug-28-2017, 12:19 AM
(This post was last modified: Aug-28-2017, 12:20 AM by Larz60+.)
Ok,
You need to learn how to read the error traceback.
It pointed directly to the error.
win was not defined in the method run as it was out of scope.
in order to make it work, you need to save win from the __init__ attributes to a variable that run can see,
thus in the code below:
self.win = win and also refer to it as self.win in the methods that use it.
new code still doesn't run to finish, but has gotten past the error you were receiving:
import wx
import wx.grid
import pandas as pd
import googlefinance.client as gf
from threading import *
class RunThread(Thread):
def __init__(self, event, win):
self.win=win
Thread.__init__(self)
self.stopped = event
self.start()
def run(self):
print('Loading 0,0 ..')
self.win.Update_5M(0, 0)
while True:
print('Loading 1,12 ..')
self.win.Update_5M(1, 12)
self.stopped.wait(20)
class Frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Thread Crash", size=(530, 742), pos=(500, 100))
wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(sizer)
self.grid = self.Create_Grid()
stopFlag = Event()
RunThread(stopFlag, self)
def Update_5M(self, n, m):
self.dfg, self.dfr = self.Load_Data_Frame(n)
self.Update_Grid(self.dfr, self.grid, 'red', m)
self.Update_Grid(self.dfg, self.grid, 'green', m)
def Create_Grid(self):
self.colno = 11
self.colsz = [43, 40, 22, 40, 44, 60, 40, 40, 40, 40, 40]
grid = wx.grid.Grid(self, size=(522, 700), pos=(0, 0))
grid.CreateGrid(1, 11)
grid.SetRowLabelSize(60)
grid.SetLabelFont(wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.NORMAL))
grid.SetDefaultCellAlignment(wx.ALIGN_RIGHT, wx.ALIGN_CENTRE)
for col in range(self.colno):
grid.SetColSize(col, self.colsz[col])
return grid
def Update_Grid(self, df_head, grid, gor, n):
cols = grid.GetNumberCols()
rows = grid.GetNumberRows()
rl =
for r in range(rows): rl.append(grid.GetRowLabelValue(r + n))
for row in range(len(df_head.index)):
r = row + n
grid.InsertRows(r, 1, False)
param = {'q': df_head.values[row, 0], 'i': "86400", 'x': "TSE", 'p': "5d"}
df = gf.get_price_data(param).tail(1)
o = 0
if len(df) < 1:
grid.DeleteRows(r, 1, False)
r -= 1
o += 1
continue
PP = (df.values[0, 1] + df.values[0, 2] + df.values[0, 3]) / 3
for col in range(self.colno):
if col != 2:
if n == 0:
if gor == 'green': grid.SetCellBackgroundColour(r, col, wx.Colour(row * 50, 200, row * 40))
if gor == 'red': grid.SetCellBackgroundColour(r, col, wx.Colour(200, row * 50, row * 40))
else:
if gor == 'green': grid.SetCellBackgroundColour(r, col, wx.Colour(row * 50, 255, row * 40))
if gor == 'red': grid.SetCellBackgroundColour(r, col, wx.Colour(255, row * 50, row * 40))
if col == 2:
d = ('%.0f' % df_head.values[row, col])
elif col == 0:
d = df_head.values[row, col]
elif col == 5:
d = format(df_head.values[row, col], "8,d")
elif col < 6:
d = ('%.2f' % df_head.values[row, col])
elif col == 6:
d = '%.2f' % (PP + df.values[0, 1] - df.values[0, 2])
elif col == 7:
d = '%.2f' % (PP * 2 - df.values[0, 2])
elif col == 8:
d = '%.2f' % PP
elif col == 9:
d = '%.2f' % (PP * 2 - df.values[0, 1])
elif col == 10:
d = '%.2f' % (PP - df.values[0, 1] + df.values[0, 2])
grid.SetCellValue(r, col, d)
for r in range(len(rl)): grid.SetRowLabelValue(r + n + 6 - o, rl[r])
def Load_Data_Frame(self, n):
df_all =
p = [['86400', '3M'], ['300', '2d']]
symb = pd.DataFrame(pd.read_csv('TSE.csv'))
for s in symb['Symbol']:
param = {'q': s, 'i': p[n][0], 'x': "TSE", 'p': p[n][1]}
df = gf.get_price_data(param)
df['T'] = s
df['HiLo'] = 100 * (df['Close'] - df['Open']) / df['Open']
df['GoR'] = df['Close'] > df['Open']
df_all.append(df)
dfg = pd.DataFrame()
dfr = pd.DataFrame()
num = len(df_all)
for s in range(num):
i = len(df_all[s].index) - 1
if i < 10: continue
nGreen, nRed, vGreen, vRed = 0, 0, 0, 0
hGreen, hRed, iGreen, iRed = 0, 0, True, True
while iGreen or iRed:
if iGreen:
if df_all[s].values[i, 7]:
nGreen += 1
if hGreen < df_all[s].values[i, 6]:
hGreen = df_all[s].values[i, 6]
else:
iGreen = False
if iRed:
if not df_all[s].values[i, 7]:
nRed += 1
if hRed > df_all[s].values[i, 6]:
hRed = df_all[s].values[i, 6]
else:
iRed = False
i -= 1
if i < 0: break
vAvg20 = pd.Series(df_all[s]['Volume']).rolling(window=20).mean()
df_all[s]['U'] = round(hGreen, 2)
df_all[s]['D'] = round(-hRed, 2)
df_all[s]['gBars'] = int(nGreen)
df_all[s]['rBars'] = int(nRed)
df_all[s]['Vg'] = vGreen / vAvg20
df_all[s]['Vr'] = vRed / vAvg20
dUp = df_all[s][['T', 'Close', 'gBars', 'U', 'Vg', 'Volume']]
dDn = df_all[s][['T', 'Close', 'rBars', 'D', 'Vr', 'Volume']]
if dfg.empty:
dfg = dUp.tail(1)
else:
dfg = dfg.append(dUp.tail(1))
if dfr.empty:
dfr = dDn.tail(1)
else:
dfr = dfr.append(dDn.tail(1))
dfg6 = dfg.sort_values('gBars', ascending=False).head(6)
dfr6 = dfr.sort_values('rBars', ascending=False).head(6)
return dfg6, dfr6
if __name__ == "__main__":
app = wx.App()
win = Frame()
win.Show()
app.MainLoop() try your best to finish, and come back if you get stuck.[/s][/s][/s][/s][/s][/s][/s][/s][/s][/s][/s][/s][/s][/s][/s][/s]
Posts: 73
Threads: 42
Joined: Jun 2017
Aug-28-2017, 02:28 AM
(This post was last modified: Aug-28-2017, 02:28 AM by ian.)
Thank you. I just did as you say but still crash. Did you try on your machine?
|