wxglade_hmi/wxglade_hmi.py
changeset 728 e0424e96e3fd
parent 725 31dade089db5
child 734 5c42cafaee15
equal deleted inserted replaced
727:3edd2f19bce2 728:e0424e96e3fd
       
     1 import wx
       
     2 import os, sys
       
     3 from xml.dom import minidom
       
     4 
       
     5 from util import opjimg
       
     6 from py_ext import PythonFileCTNMixin
       
     7 
       
     8 class WxGladeHMI(PythonFileCTNMixin):
       
     9 
       
    10     ConfNodeMethods = [
       
    11         {"bitmap" : opjimg("editWXGLADE"),
       
    12          "name" : _("WXGLADE GUI"),
       
    13          "tooltip" : _("Edit a WxWidgets GUI with WXGlade"),
       
    14          "method" : "_editWXGLADE"},
       
    15     ]
       
    16 
       
    17     def ConfNodePath(self):
       
    18         return os.path.join(os.path.dirname(__file__))
       
    19 
       
    20     def _getWXGLADEpath(self):
       
    21         # define name for IEC raw code file
       
    22         return os.path.join(self.CTNPath(), "hmi.wxg")
       
    23 
       
    24     def launch_wxglade(self, options, wait=False):
       
    25         from wxglade import __file__ as fileName
       
    26         path = os.path.dirname(fileName)
       
    27         glade = os.path.join(path, 'wxglade.py')
       
    28         if wx.Platform == '__WXMSW__':
       
    29             glade = "\"%s\""%glade
       
    30         mode = {False:os.P_NOWAIT, True:os.P_WAIT}[wait]
       
    31         os.spawnv(mode, sys.executable, ["\"%s\""%sys.executable] + [glade] + options)
       
    32 
       
    33 
       
    34     def CTNGenerate_C(self, buildpath, locations):
       
    35         """
       
    36         Return C code generated by iec2c compiler 
       
    37         when _generate_softPLC have been called
       
    38         @param locations: ignored
       
    39         @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
       
    40         """
       
    41         
       
    42         current_location = self.GetCurrentLocation()
       
    43         # define a unique name for the generated C file
       
    44         location_str = "_".join(map(lambda x:str(x), current_location))
       
    45         
       
    46         runtimefile_path = os.path.join(buildpath, "runtime_%s.py"%location_str)
       
    47         runtimefile = open(runtimefile_path, 'w')
       
    48         
       
    49         hmi_frames = {}
       
    50         
       
    51         wxgfile_path=self._getWXGLADEpath()
       
    52         if os.path.exists(wxgfile_path):
       
    53             wxgfile = open(wxgfile_path, 'r')
       
    54             wxgtree = minidom.parse(wxgfile)
       
    55             wxgfile.close()
       
    56             
       
    57             for node in wxgtree.childNodes[1].childNodes:
       
    58                 if node.nodeType == wxgtree.ELEMENT_NODE:
       
    59                     hmi_frames[node._attrs["name"].value] =  node._attrs["class"].value
       
    60                     
       
    61             hmipyfile_path=os.path.join(self._getBuildPath(), "hmi.py")
       
    62             if wx.Platform == '__WXMSW__':
       
    63                 wxgfile_path = "\"%s\""%wxgfile_path
       
    64                 wxghmipyfile_path = "\"%s\""%hmipyfile_path
       
    65             else:
       
    66                 wxghmipyfile_path = hmipyfile_path
       
    67             self.launch_wxglade(['-o', wxghmipyfile_path, '-g', 'python', wxgfile_path], wait=True)
       
    68             
       
    69             hmipyfile = open(hmipyfile_path, 'r')
       
    70             runtimefile.write(hmipyfile.read())
       
    71             hmipyfile.close()
       
    72         
       
    73         runtimefile.write(self.GetPythonCode())
       
    74         runtimefile.write("""
       
    75 %(declare)s
       
    76 
       
    77 def _runtime_%(location)s_begin():
       
    78     global %(global)s
       
    79     
       
    80     def OnCloseFrame(evt):
       
    81         wx.MessageBox(_("Please stop PLC to close"))
       
    82     
       
    83     %(init)s
       
    84     
       
    85 def _runtime_%(location)s_cleanup():
       
    86     global %(global)s
       
    87     
       
    88     %(cleanup)s
       
    89 
       
    90 """ % {"location": location_str,
       
    91        "declare": "\n".join(map(lambda x:"%s = None" % x, hmi_frames.keys())),
       
    92        "global": ",".join(hmi_frames.keys()),
       
    93        "init": "\n".join(map(lambda x: """
       
    94     %(name)s = %(class)s(None)
       
    95     %(name)s.Bind(wx.EVT_CLOSE, OnCloseFrame)
       
    96     %(name)s.Show()
       
    97 """ % {"name": x[0], "class": x[1]},
       
    98                              hmi_frames.items())),
       
    99        "cleanup": "\n    ".join(map(lambda x:"%s.Destroy()" % x, hmi_frames.keys()))})
       
   100         runtimefile.close()
       
   101         
       
   102         return [], "", False, ("runtime_%s.py"%location_str, file(runtimefile_path,"rb"))
       
   103 
       
   104     def _editWXGLADE(self):
       
   105         wxg_filename = self._getWXGLADEpath()
       
   106         open_wxglade = True
       
   107         if not self.GetCTRoot().CheckProjectPathPerm():
       
   108             dialog = wx.MessageDialog(self.GetCTRoot().AppFrame,
       
   109                                       _("You don't have write permissions.\nOpen wxGlade anyway ?"),
       
   110                                       _("Open wxGlade"),
       
   111                                       wx.YES_NO|wx.ICON_QUESTION)
       
   112             open_wxglade = dialog.ShowModal() == wx.ID_YES
       
   113             dialog.Destroy()
       
   114         if open_wxglade:
       
   115             if not os.path.exists(wxg_filename):
       
   116                 hmi_name = self.BaseParams.getName()
       
   117                 open(wxg_filename,"w").write("""<?xml version="1.0"?>
       
   118     <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">
       
   119         <object class="%(class)s" name="%(name)s" base="EditFrame">
       
   120             <style>wxDEFAULT_FRAME_STYLE</style>
       
   121             <title>frame_1</title>
       
   122         </object>
       
   123     </application>
       
   124     """ % {"name": hmi_name, "class": "Class_%s" % hmi_name})
       
   125             if wx.Platform == '__WXMSW__':
       
   126                 wxg_filename = "\"%s\""%wxg_filename
       
   127             self.launch_wxglade([wxg_filename])