Fix error about missing attribute 'timeout' that happens sometimes during compilation
The fix [1476:49f1763a5613] of the problem with following trace was wrong.
Traceback (most recent call last):
File "./Beremiz.py", line 1229, in run_with_except_hook
run_old(*args, **kw)
File
"/home/developer/WorkData/PLC/beremiz/beremiz/util/ProcessLogger.py",
line 68, in run
self.endcallback(self.Proc.pid, err)
File
"/home/developer/WorkData/PLC/beremiz/beremiz/util/ProcessLogger.py",
line 169, in finish
if self.timeout: self.timeout.cancel()
AttributeError: ProcessLogger instance has no attribute 'timeout'
The problem was that compilation process was finished before the timeout attribute is set.
Now timeout is set before launcing of compilation process.
import wx
import os, sys, shutil
from xml.dom import minidom
from py_ext import PythonFileCTNMixin
class WxGladeHMI(PythonFileCTNMixin):
ConfNodeMethods = [
{"bitmap" : "editWXGLADE",
"name" : _("WXGLADE GUI"),
"tooltip" : _("Edit a WxWidgets GUI with WXGlade"),
"method" : "_editWXGLADE"},
]
def GetIconName(self):
return "wxGlade"
def ConfNodePath(self):
return os.path.join(os.path.dirname(__file__))
def _getWXGLADEpath(self, project_path=None):
if project_path is None:
project_path = self.CTNPath()
# define name for wxGlade gui file
return os.path.join(project_path, "hmi.wxg")
def launch_wxglade(self, options, wait=False):
from wxglade import __file__ as fileName
path = os.path.dirname(fileName)
glade = os.path.join(path, 'wxglade.py')
if wx.Platform == '__WXMSW__':
glade = "\"%s\""%glade
mode = {False:os.P_NOWAIT, True:os.P_WAIT}[wait]
os.spawnv(mode, sys.executable, ["\"%s\""%sys.executable] + [glade] + options)
def OnCTNSave(self, from_project_path=None):
if from_project_path is not None:
shutil.copyfile(self._getWXGLADEpath(from_project_path),
self._getWXGLADEpath())
return PythonFileCTNMixin.OnCTNSave(self, from_project_path)
def CTNGenerate_C(self, buildpath, locations):
hmi_frames = []
wxgfile_path=self._getWXGLADEpath()
if os.path.exists(wxgfile_path):
wxgfile = open(wxgfile_path, 'r')
wxgtree = minidom.parse(wxgfile)
wxgfile.close()
for node in wxgtree.childNodes[1].childNodes:
if node.nodeType == wxgtree.ELEMENT_NODE:
hmi_frames.append({
"name" : node.getAttribute("name"),
"class" : node.getAttribute("class"),
"handlers" : [
hnode.firstChild.data for hnode in
node.getElementsByTagName("handler")]})
hmipyfile_path=os.path.join(self._getBuildPath(), "hmi.py")
if wx.Platform == '__WXMSW__':
wxgfile_path = "\"%s\""%wxgfile_path
wxghmipyfile_path = "\"%s\""%hmipyfile_path
else:
wxghmipyfile_path = hmipyfile_path
self.launch_wxglade(['-o', wxghmipyfile_path, '-g', 'python', wxgfile_path], wait=True)
hmipyfile = open(hmipyfile_path, 'r')
define_hmi = hmipyfile.read().decode('utf-8')
hmipyfile.close()
else:
define_hmi = ""
declare_hmi = "\n".join(["%(name)s = None\n" % x +
"\n".join(["%(class)s.%(h)s = %(h)s"%
dict(x,h=h) for h in x['handlers']])
for x in hmi_frames])
global_hmi = ("global %s\n"%",".join(
[x["name"] for x in hmi_frames])
if len(hmi_frames) > 0 else "")
init_hmi = "\n".join(["""\
def OnCloseFrame(evt):
wx.MessageBox(_("Please stop PLC to close"))
%(name)s = %(class)s(None)
%(name)s.Bind(wx.EVT_CLOSE, OnCloseFrame)
%(name)s.Show()
""" % x for x in hmi_frames])
cleanup_hmi = "\n".join(
["if %(name)s is not None: %(name)s.Destroy()" % x
for x in hmi_frames])
self.PreSectionsTexts = {
"globals":define_hmi,
"start":global_hmi,
"stop":global_hmi + cleanup_hmi
}
self.PostSectionsTexts = {
"globals":declare_hmi,
"start":init_hmi,
}
return PythonFileCTNMixin.CTNGenerate_C(self, buildpath, locations)
def _editWXGLADE(self):
wxg_filename = self._getWXGLADEpath()
open_wxglade = True
if not self.GetCTRoot().CheckProjectPathPerm():
dialog = wx.MessageDialog(self.GetCTRoot().AppFrame,
_("You don't have write permissions.\nOpen wxGlade anyway ?"),
_("Open wxGlade"),
wx.YES_NO|wx.ICON_QUESTION)
open_wxglade = dialog.ShowModal() == wx.ID_YES
dialog.Destroy()
if open_wxglade:
if not os.path.exists(wxg_filename):
hmi_name = self.BaseParams.getName()
open(wxg_filename,"w").write("""<?xml version="1.0"?>
<application path="" name="" class="" option="0" language="python" top_window="%(name)s" encoding="UTF-8" use_gettext="0" overwrite="0" use_new_namespace="1" for_version="2.8" is_template="0">
<object class="%(class)s" name="%(name)s" base="EditFrame">
<style>wxDEFAULT_FRAME_STYLE</style>
<title>frame_1</title>
<object class="wxBoxSizer" name="sizer_1" base="EditBoxSizer">
<orient>wxVERTICAL</orient>
<object class="sizerslot" />
</object>
</object>
</application>
""" % {"name": hmi_name, "class": "Class_%s" % hmi_name})
if wx.Platform == '__WXMSW__':
wxg_filename = "\"%s\""%wxg_filename
self.launch_wxglade([wxg_filename])