Dear all,
I have been trying to figure out how I can execute a Python script from a GUI but with no luck. Searching the internet I have come across several ideas (threading, subprocess, etc…) but I do not seem to get it right. To illustrate what I need to do, below is a simple GUI that I have built.
############################################################
import wx
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE | wx.STAY_ON_TOP
wx.Frame.__init__(self, *args, **kwds)
self.SetSize((400, 300))
self.SetTitle("TEST")
self.panel_1 = wx.Panel(self, wx.ID_ANY)
sizer_1 = wx.BoxSizer(wx.VERTICAL)
grid_sizer_1 = wx.FlexGridSizer(5, 2, 1, 1)
sizer_1.Add(grid_sizer_1, 1, wx.EXPAND, 0)
label_1 = wx.StaticText(self.panel_1, wx.ID_ANY, "x")
grid_sizer_1.Add(label_1, 0, wx.ALL, 5)
self.text_ctrl_1 = wx.TextCtrl(self.panel_1, wx.ID_ANY, "")
grid_sizer_1.Add(self.text_ctrl_1, 0, 0, 0)
label_2 = wx.StaticText(self.panel_1, wx.ID_ANY, "y")
grid_sizer_1.Add(label_2, 0, wx.ALL, 5)
self.text_ctrl_2 = wx.TextCtrl(self.panel_1, wx.ID_ANY, "")
grid_sizer_1.Add(self.text_ctrl_2, 0, 0, 0)
grid_sizer_1.Add((0, 0), 0, 0, 0)
self.button_1 = wx.Button(self.panel_1, wx.ID_ANY, "Save")
self.button_1.SetFocus()
grid_sizer_1.Add(self.button_1, 0, 0, 0)
grid_sizer_1.Add((0, 0), 0, 0, 0)
self.button_2 = wx.Button(self.panel_1, wx.ID_ANY, "Start")
grid_sizer_1.Add(self.button_2, 0, 0, 0)
grid_sizer_1.Add((0, 0), 0, 0, 0)
self.button_3 = wx.Button(self.panel_1, wx.ID_ANY, "Stop")
grid_sizer_1.Add(self.button_3, 0, 0, 0)
self.panel_1.SetSizer(sizer_1)
self.Layout()
self.Bind(wx.EVT_BUTTON, self.OnClick_Save, self.button_1)
self.Bind(wx.EVT_BUTTON, self.OnClick_Start, self.button_2)
self.Bind(wx.EVT_BUTTON, self.OnClick_Stop, self.button_3)
def OnClick_Save(self, event):
data = []
x = float(self.text_ctrl_1.GetValue())
data.append(x)
y = float(self.text_ctrl_2.GetValue())
data.append(y)
event.Skip()
def OnClick_Start(self, event):
# Button "Start" runs the module (script)
event.Skip()
def OnClick_Stop(self, event):
# Button "Stop" aborts the run
event.Skip()
class MyApp(wx.App):
def OnInit(self):
self.frame = MyFrame(None, wx.ID_ANY, "")
self.SetTopWindow(self.frame)
self.frame.Show()
return True
if __name__ == "__main__":
Test = MyApp(0)
Test.MainLoop()
################################################################
For a start, the external Python script I am trying to run from the above GUI is a sympy code:
################################################################
import sympy
from sympy import symbols, sin, cos, N
x, y = symbols('x, y')
z = N(sin(x) + cos(y))
print(z)
################################################################
What I am hoping to achieve is:
- Running the external script after entering the values of x and y in the text controls and clicking the ‘Save’ followed by the ‘Start’ buttons.
- Being able to abort the run by clicking the ‘Stop’ button.
- Writing the output (results of the calculation) to a text file (preferred method ) or to the GUI.
Please note that the real life scripts that I will be running will take from several minutes to possibly several hours to complete.
If it is of help, here are the details of what I am using: Python 3.8.5; wxPython 4.1.0 and MSW 10 64 bit.
Any help is highly appreciated.
Many thanks in advance.
omar