diff --git a/trunk/forms.py b/trunk/forms.py index 42a4b66..78e866f 100644 --- a/trunk/forms.py +++ b/trunk/forms.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import wx +import wx.gizmos import wx.propgrid as wxpg ID_TEST = wx.NewId() @@ -25,9 +26,12 @@ class MainFrame (wx.Frame): bSizer4 = wx.BoxSizer(wx.VERTICAL) - self.m_user_models = wx.TreeCtrl(self, + self.m_user_models = wx.gizmos.TreeListCtrl(self, style = wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT | wx.TR_EDIT_LABELS) self.m_user_models.SetMinSize(wx.Size(-1,200)) + self.m_user_models.AddColumn("Model name") + self.m_user_models.AddColumn("Status") + self.m_user_models.AddColumn("Progress") bSizer4.Add(self.m_user_models, 0, wx.ALL|wx.EXPAND, 1) @@ -38,8 +42,8 @@ class MainFrame (wx.Frame): bSizer3.Add(bSizer4, 1, wx.EXPAND, 5) - self.m_job_list = wx.ListCtrl(self, style = wx.LC_LIST) - self.m_job_list.SetMinSize(wx.Size(150,-1)) + self.m_job_list = wx.ListBox(self)#, style = wx.LC_LIST) + self.m_job_list.SetMinSize(wx.Size(200,-1)) bSizer3.Add(self.m_job_list, 0, wx.ALL|wx.EXPAND, 1) diff --git a/trunk/opal.py b/trunk/opal.py index d30af70..4bc36ce 100644 --- a/trunk/opal.py +++ b/trunk/opal.py @@ -16,6 +16,10 @@ import task import wx import wx.propgrid as wxpg import forms +import time +import datetime +import os +import threading #----------------------------------------------------------------------------- # Главная форма @@ -25,27 +29,71 @@ class MainFrame(forms.MainFrame): def __init__(self): forms.MainFrame.__init__(self, None) - s = server.LocalServer() - s.LoadTasksDescriptions() + self.server = s = server.LocalServer() + self.server.LoadTasksDescriptions() ds = s.GetTasksDescriptions() models = [] for d in ds: models.extend(d.GetModelsDescriptions()) - model = models[0] + s.Start() - self.m_user_models.Bind(wx.EVT_TREE_ITEM_ACTIVATED, + self.m_user_models.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnModelActivated) self.m_params.Bind(wxpg.EVT_PG_CHANGING, self.OnParamChanging) + self.m_params.Bind(wxpg.EVT_PG_CHANGED, + self.OnParamChanged) self.Bind(wx.EVT_MENU, self.OnTest, id = forms.ID_TEST) self.Bind(wx.EVT_MENU, self.OnDuplicate, id = forms.ID_DUPLICATE) + self.Bind(wx.EVT_CLOSE, self.OnClose) + self.Bind(wx.EVT_IDLE, self.OnIdle) + self.m_params.AddPage('fp') + ov = threading.Thread(target = self.Overseer) + ov.daemon = 1 + ov.start() + self.NewProject(model) + + def OnClose(self, event): + self.server.Stop() + self.Destroy() + + # todo1 вменяемый цикл обхода! + def Overseer(self): + + def SeeTheItem(item): + um = self.m_user_models + md = um.GetPyData(item) + print um.GetItemText(item) + job = md.job + if job: + t = os.path.basename(job.taskd.execpath) + p = job.percent * 100 + print t, p + um.SetItemText(item, '{}: {:.2F}%'.format(t, p), 1) + + child, cookie = um.GetFirstChild() + while child.IsOk(): + SeeTheItem(child) + child, cookie = um.GetNextChild(child, cookie) + + #try: + server = self.server + while True: + print 'cycle' + um = self.m_user_models + item = um.GetFirstVisibleItem() + SeeTheItem(item) + time.sleep(0.5) + #except: + # pass + def NewProject(self, project): # 1. загрузить спецификации модели # 2. создать одну модель по умолчанию @@ -54,10 +102,33 @@ class MainFrame(forms.MainFrame): root = um.AddRoot('') data = task.DataDefinition(model) - child = um.AppendItem(root, u'Обычная') + child = um.AppendItem(root, 'Default') um.SetPyData(child, data) + um.SetItemText(child, '234', 1) def SelectUserModel(self, model_def): + + def SelectProperty(param_type): + """ + По указанному имени типа возвращает "свойство" для списка "свойств" + + Смотри руководство пользователя для того, чтобы получить полную + информацию о всех типах данных, используемых в Opal. + """ + if param_type == 'bool': + return wxpg.BoolProperty + elif param_type == 'int': + return wxpg.IntProperty + elif param_type == 'float' or param_type == 'double': + return wxpg.FloatProperty + elif param_type == 'string': + return wxpg.StringProperty + elif param_type == 'list': + return wxpg.ArrayStringProperty + else: + # очень плохо, если это произошло + raise KeyError() + msg = model_def.PackParams() pg = self.m_params pg.ClearPage(0) @@ -65,26 +136,43 @@ class MainFrame(forms.MainFrame): for k, v in model_def.params.iteritems(): p = model_def.DD[k] title = p.GetTitle() or k - pid = pg.Append(wxpg.StringProperty(title, value=str(v))) + prop = SelectProperty(p.GetType()) + pid = pg.Append(prop(title, value = v)) pg.SetPropertyClientData(pid, k) pg.SetPropertyHelpString(pid, p.GetComment()) + pd = model_def.PackParams() + self.SetStatusText(pd, 0) + def OnModelActivated(self, event): item = event.GetItem() data = self.m_user_models.GetPyData(item) - self.SelectUserModel(data) + if data: + self.SelectUserModel(data) def OnParamChanging(self, event): - value = event.GetValue() - print repr(value) + #value = event.GetValue() + #print repr(value) #wx.MessageBox(value, 'changing') #event.Veto() + pass + + def OnParamChanged(self, event): + prop = event.GetProperty() + if not prop: + return + value = prop.GetValue() + param = prop.GetClientData() + um = self.m_user_models + id = um.GetSelection() + md = um.GetItemPyData(id) + md[param] = value def OnTest(self, event): um = self.m_user_models id = um.GetSelection() md = um.GetItemPyData(id) - wx.MessageBox(md.PackParams()) + #wx.MessageBox(md.PackParams()) md.Flush() #wx.MessageBox('test') @@ -97,7 +185,18 @@ class MainFrame(forms.MainFrame): child = um.AppendItem(parent, title + ' Copy') um.SetPyData(child, md.Copy()) - + def OnIdle(self, event): +## server = self.server +## self.m_job_list.Freeze() +## self.m_job_list.Clear() +## with server.queue_lock: +## for j in server.jobs_queue: +## t = os.path.dirname(j.taskd.execpath) +## p = j.percent * 100.0 +## self.m_job_list.Append('{}: {:.2}%'.format(t, p)) +## self.m_job_list.Thaw() + pass + #time.sleep(1) #----------------------------------------------------------------------------- # Приложение diff --git a/trunk/server.py b/trunk/server.py index 5178b3c..11e5c67 100644 --- a/trunk/server.py +++ b/trunk/server.py @@ -18,6 +18,7 @@ import time import datetime import threading import subprocess +import logging import task @@ -42,11 +43,10 @@ class LocalServer: """ def __init__(self): self.max_workers = 2 - self.task_descrs = [] self.jobs_queue = [] self.log = None - + self.running = False self.queue_lock = threading.Lock() # init actions @@ -54,11 +54,8 @@ class LocalServer: self.log = open('log.txt', 'w') self.WriteToLog('local server initialized') - for i in xrange(2): - worker = Worker(self.jobs_queue, self.queue_lock) - worker.start() - def Close(self): + self.Stop() self.WriteToLog('local server closed\n') def __del__(self): @@ -71,10 +68,13 @@ class LocalServer: print msg def Start(self): - pass + self.running = True + for i in xrange(self.max_workers): + worker = Worker(self.jobs_queue, self.queue_lock, self.running) + worker.start() def Stop(self): - pass + self.running = False def TestTaskData(self, data): pass @@ -133,10 +133,11 @@ class LocalServer: class Worker(threading.Thread): number = 0 - def __init__(self, queue, lock): + def __init__(self, queue, lock, runflag): threading.Thread.__init__(self) self.queue = queue self.lock = lock + self.runflag = runflag self.daemon = True WriteToLog('worker started') self.id = Worker.number @@ -154,13 +155,15 @@ class Worker(threading.Thread): # и, если нашли, приступаем к выполнению if job: WriteToLog("{} started!".format(self.id)) - job.Start() + job.Start(self.runflag) WriteToLog("{} finished!".format(self.id)) else: time.sleep(1) def run(self): while True: + if not self.runflag: + return self.Cycle() #------------------------------------------------------------------------------- @@ -170,6 +173,7 @@ JOB_BUSY = 1 JOB_RUNNING = 2 JOB_STOPPED = 3 JOB_COMPLETED = 4 +JOB_DROPPED = 5 class Job: def __init__(self, taskd, datadump): @@ -204,7 +208,7 @@ class Job: self.comment = data.get('comment', '') - def Start(self): + def Start(self, runflag): try: self.state = JOB_RUNNING execpath = self.taskd.execpath @@ -223,6 +227,10 @@ class Job: msg = ostream.readline() #msg = msg.strip() self.ProcessMsg(msg) + + if not runflag: + self.Stop() + # todo вписать исключения, которые относятся к JSON & dict except Exception, e: #WriteToLog('Income msg failed: ' + str(e)) pass diff --git a/trunk/tasks/testt.json b/trunk/tasks/testt.json index a04be05..19a39ba 100644 --- a/trunk/tasks/testt.json +++ b/trunk/tasks/testt.json @@ -15,7 +15,7 @@ "params": { "r": { - "type": "double", + "type": "float", "default": 6.28, "title": "Right edge", "comment": "Right edge" diff --git a/trunk/tasks/testt.py b/trunk/tasks/testt.py index a214875..aa2f8ec 100644 --- a/trunk/tasks/testt.py +++ b/trunk/tasks/testt.py @@ -81,7 +81,7 @@ def main(): res.append([l, y]) write(answer(round(l / r, 2))) l += h - time.sleep(0.5) + time.sleep(0.2) write(result(res))