Ask Your Question
0

wxPython & PSSE threading

asked 2022-05-25 12:05:17 -0500

acd1 gravatar image

updated 2022-05-25 12:06:17 -0500

I have been trying to develop a GUI using wxPython for a long-running PSSE process which remains responsive while PSSE is doing its work. I'm not at all experienced with multithreading in any programming language, so I've generally just been following the structure from the first script shown here: https://wiki.wxpython.org/LongRunning...

It has become clear to me that invoking PSSE through the psspy API is not the same as running standalone python code when it comes to multithreading.

Here is my general code structure and an example GUI. There are two buttons in this sample GUI as well as two text fields. The "Add" button just increments the first text field by 1 and only exists as a check to see if the GUI is responsive. The "Run" button calls a long running PSSE process in a separate worker thread (or so I hoped) and then updates the second text field to '999' when it's finished. The script runs outside PSSE, and only instantiates PSSE when it's called on by the user.

Here's the kicker: if I replace long_running_psse_process() with a simple time.sleep(10), then the GUI is responsive as I would have expected. However, as soon as PSSE enters the picture, the GUI hangs whenever PSSE is working on something.


I would like to know if this sort of multi-threading is possible, or if something about the psspy API precludes this approach. Does anyone have any experience in getting something like this working well?

I am using PSSE 34.9.3 and Python 2.7.18 if that matters.

import wx
import os
import sys
import threading
import time

syspath = r"C:\Program Files (x86)\PTI\PSSE34\PSSPY27"
ospath = r"C:\Program Files (x86)\PTI\PSSE34\PSSBIN"
sys.path.append(syspath)
os.environ['PATH'] += ';' + ospath
os.environ['PATH'] += ';' + syspath

import psspy
import redirect

EVT_RESULT_ID = wx.NewId()

def main():
    app = wx.App(None)
    frame = main_frame(None, title='Test Multithreading')
    frame.SetSize(300, 100)
    frame.Show()
    app.MainLoop()

def EVT_RESULT(win, func):
    win.Connect(-1, -1, EVT_RESULT_ID, func)

class ResultEvent(wx.PyEvent):
    def __init__(self, data):
        wx.PyEvent.__init__(self)
        self.SetEventType(EVT_RESULT_ID)
        self.data = data

class WorkerThread(threading.Thread):
    def __init__(self, notify_window):
        threading.Thread.__init__(self)
        self._notify_window = notify_window

    def run(self):
        long_running_psse_process()
        wx.PostEvent(self._notify_window, ResultEvent(999))

class main_frame(wx.Frame):
    def __init__(self, parent, title):
        super(main_frame, self).__init__(parent, title=title,
                                         style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER)
        self.CenterOnScreen(direction=wx.HORIZONTAL)
        self.x = 0
        self.worker = None

        EVT_RESULT(self, self.on_finish)

        pnl = wx.Panel(self)
        sizer = wx.GridBagSizer(2, 2)

        button_add = wx.Button(pnl, label='Add', size=(90, 28))
        button_add.Bind(wx.EVT_BUTTON, self.on_add)
        sizer.Add(button_add, pos=(0, 0), border=10)

        self.x_text = wx.StaticText(pnl, label='0')
        sizer.Add(self.x_text, pos=(0, 1), border=10)

        button_run = wx.Button(pnl, label='Run', size=(90, 28))
        button_run.Bind(wx.EVT_BUTTON, self.on_run)
        sizer.Add(button_run, pos=(1, 0), border=10)

        self.y_text = wx.StaticText ...
(more)
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2022-05-26 10:13:51 -0500

jconto gravatar image

I use the multiprocessing module to run multiple instances of PSSe but avoid GUI's with parallel processing.

Try putting the initial calls to PSSe inside the longrunningpsse_process().

Also, does the python code in longrunningpsse_process() closes PSSe and any log file before returning?

edit flag offensive delete link more

Comments

Thanks for the comment. I have been using the threading module, but it looks like the multiprocessing module may do the trick. I'll dig into that some more. The long_running_psse_process() code both opens and closes PSSE and all log files.

acd1 gravatar imageacd1 ( 2022-05-26 16:45:40 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

[hide preview]

Question Tools

1 follower

Stats

Asked: 2022-05-25 12:05:17 -0500

Seen: 79 times

Last updated: May 26