GUI added

This commit is contained in:
anwinged 2012-04-17 10:29:39 +00:00
parent c7b38a6506
commit 8da3143df3
7 changed files with 202 additions and 34 deletions

77
forms.py Normal file
View File

@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
import wx
import wx.propgrid as wxpg
ID_TEST = wx.NewId()
ID_DUPLICATE = wx.NewId()
ID_DUPLICATE_MODEL = wx.NewId()
ID_DELETE_MODEL = wx.NewId()
ID_PROCESS_MODEL = wx.NewId()
class MainFrame (wx.Frame):
def __init__(self, parent):
wx.Frame.__init__ (self, parent, title = 'Opal', size = wx.Size(873,594))
self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
bSizer3 = wx.BoxSizer(wx.HORIZONTAL)
self.m_specs = wx.TreeCtrl(self, style = wx.TR_DEFAULT_STYLE|wx.TR_HIDE_ROOT)
self.m_specs.SetMinSize(wx.Size(150,-1))
bSizer3.Add(self.m_specs, 0, wx.ALL|wx.EXPAND, 1)
bSizer4 = wx.BoxSizer(wx.VERTICAL)
self.m_user_models = wx.TreeCtrl(self,
style = wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT | wx.TR_EDIT_LABELS)
self.m_user_models.SetMinSize(wx.Size(-1,200))
bSizer4.Add(self.m_user_models, 0, wx.ALL|wx.EXPAND, 1)
# WARNING: wxPython code generation isn't supported for this widget yet.
self.m_params = wxpg.PropertyGridManager(self,
style = wxpg.PG_TOOLBAR)
bSizer4.Add(self.m_params, 1, wx.EXPAND |wx.ALL, 1)
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))
bSizer3.Add(self.m_job_list, 0, wx.ALL|wx.EXPAND, 1)
sbar = wx.StatusBar(self)
self.SetStatusBar(sbar)
mbar = self.BuildMenu()
self.SetMenuBar(mbar)
self.SetSizer(bSizer3)
self.Layout()
self.Centre(wx.BOTH)
def __del__(self):
pass
def BuildMenu(self):
menubar = wx.MenuBar()
menu = wx.Menu()
menu.Append(1, "&Open\tCtrl+O")
menubar.Append(menu, '&File')
menu = wx.Menu()
menu.Append(ID_TEST, "&Test\tCtrl+U")
menu.Append(ID_DUPLICATE, "&Duplicate\tCtrl+D")
menubar.Append(menu, '&Model')
menu = wx.Menu()
menu.Append(3, "&Log In\tCtrl+L")
menu.Append(2, "&Options\tCtrl+P")
menubar.Append(menu, '&Help')
return menubar

View File

@ -112,7 +112,7 @@ ok
Перед тем как перейти к описанию структуры, описывающей зачаду и ее модели, следует рассказать о типах данных, которые применяются в “Opal”. Далее будем говорить только о тех полях, которые встречаются в задачах, моделях и методах. Перед тем как перейти к описанию структуры, описывающей зачаду и ее модели, следует рассказать о типах данных, которые применяются в “Opal”. Далее будем говорить только о тех полях, которые встречаются в задачах, моделях и методах.
Тип очень важная часть описания данных. Хотя без него можно было бы обойтись, предоставив пользователям полный контроль над передаваемыми данными, этого лучше избежать. Все дело в том, что тип является мощным инструментом контроля целостности передаваемых данных, не позволяя использовать, скажем, строку там, где должно быть целое число. Тип --- очень важная часть описания данных. Хотя без него можно было бы обойтись, предоставив пользователям полный контроль над передаваемыми данными, этого лучше избежать. Все дело в том, что тип является мощным инструментом контроля целостности передаваемых данных, не позволяя использовать, скажем, строку там, где должно быть целое число.
В описании поля используется следующий синтаксис: В описании поля используется следующий синтаксис:
“name”: “type [choice list] [default value] [title title] “name”: “type [choice list] [default value] [title title]
@ -151,14 +151,12 @@ ok
Период Период
[0:0:0, 12:0:0] [0:0:0, 12:0:0]
\subsection{Логический тип} \subsection{Логический тип \emph{bool}}
bool
Значения: true, false Значения: true, false
Логический тип один из основополагающих типов данных. Он может принимать всего два значения: истина и ложь. Отлично подходит для создания выключателей (или переключателей) дополнительных опций модели. Логический тип один из основополагающих типов данных. Он может принимать всего два значения: истина и ложь. Отлично подходит для создания выключателей (или переключателей) дополнительных опций модели.
Присутствует в JSON. Присутствует в JSON.
\subsection{Целочисленный тип} \subsection{Целочисленный тип \emph{int}}
int
Значения: от -231 до 231-1 (4 байта) Значения: от -231 до 231-1 (4 байта)
Тип данных для хранения целых чисел со знаком. Пожалуй, еще более основной тип, чем логический. Если вы не собираетесь работать с большими целыми числами (к примеру, рассчитывать госдолг США) то представленного диапазона хватит для большинства задач. Тип данных для хранения целых чисел со знаком. Пожалуй, еще более основной тип, чем логический. Если вы не собираетесь работать с большими целыми числами (к примеру, рассчитывать госдолг США) то представленного диапазона хватит для большинства задач.
Присутствует в JSON. Присутствует в JSON.
@ -169,8 +167,7 @@ float
Тип данных с плавающей точкой предназначен для хранения и обработки действительных чисел. Тип данных с плавающей точкой предназначен для хранения и обработки действительных чисел.
Присутствует в JSON. Присутствует в JSON.
\subsection{Строковый тип} \subsection{Строковый тип \emph{string}}
string
Строковый тип служит для хранения символов. Отсутствует разделение на строки и символы как во многих языках программирования. Это сделано для того, чтобы упростить работу с данными. Строки можно использовать в качестве комментариев. В качестве нетривиального примера можно привести использование строк вместе с оператором выбора в качестве перечисляемого типа (аналог enum): Строковый тип служит для хранения символов. Отсутствует разделение на строки и символы как во многих языках программирования. Это сделано для того, чтобы упростить работу с данными. Строки можно использовать в качестве комментариев. В качестве нетривиального примера можно привести использование строк вместе с оператором выбора в качестве перечисляемого типа (аналог enum):
string choice [a, b, c] string choice [a, b, c]
При записи строк в определении поля данных нужно быть внимательным с использованием кавычек. Кавычки внутри описания поля нужно экранировать символом обратного слеша \\. Лучше это будет видно на примере: При записи строк в определении поля данных нужно быть внимательным с использованием кавычек. Кавычки внутри описания поля нужно экранировать символом обратного слеша \\. Лучше это будет видно на примере:
@ -178,8 +175,7 @@ string
Чтобы не запутаться надо просто помнить, что вы описываете строку в строке. Чтобы не запутаться надо просто помнить, что вы описываете строку в строке.
Присутствует в JSON. Присутствует в JSON.
\subsection{Тип момента времени} \subsection{Тип момента времени \emph{time}}
time
Значения: от "1000-01-01 00:00:00" до "9999-12-31 23:59:59" Значения: от "1000-01-01 00:00:00" до "9999-12-31 23:59:59"
Является аналогом типа данных timestamp. При описании значений этого типа можно описывать как все поле целиком, так и использовать его части отдельно (время и дату). Отсутствующая часть будет заменена значением по умолчанию. Примеры: Является аналогом типа данных timestamp. При описании значений этого типа можно описывать как все поле целиком, так и использовать его части отдельно (время и дату). Отсутствующая часть будет заменена значением по умолчанию. Примеры:
“12:10:00” “12:10:00”

108
opal.py
View File

@ -13,23 +13,109 @@
import server import server
import task import task
import wx
import wx.propgrid as wxpg
import forms
class Project: #-----------------------------------------------------------------------------
pass # Главная форма
#-----------------------------------------------------------------------------
class MainFrame(forms.MainFrame):
def __init__(self):
forms.MainFrame.__init__(self, None)
def main():
import pprint
s = server.LocalServer() s = server.LocalServer()
s.LoadTasksDescriptions() s.LoadTasksDescriptions()
ds = s.GetTasksDescriptions() ds = s.GetTasksDescriptions()
ms = [] models = []
for d in ds: for d in ds:
ms.extend(d.GetModelsDescriptions()) models.extend(d.GetModelsDescriptions())
m = ms[0] model = models[0]
pprint.pprint(m.data)
print m.GetSpecifications() self.m_user_models.Bind(wx.EVT_TREE_ITEM_ACTIVATED,
self.OnModelActivated)
self.m_params.Bind(wxpg.EVT_PG_CHANGING,
self.OnParamChanging)
if __name__ == '__main__': self.Bind(wx.EVT_MENU, self.OnTest, id = forms.ID_TEST)
main() self.Bind(wx.EVT_MENU, self.OnDuplicate, id = forms.ID_DUPLICATE)
self.m_params.AddPage('fp')
self.NewProject(model)
def NewProject(self, project):
# 1. загрузить спецификации модели
# 2. создать одну модель по умолчанию
model = project
um = self.m_user_models
root = um.AddRoot('')
data = task.DataDefinition(model)
child = um.AppendItem(root, u'Обычная')
um.SetPyData(child, data)
def SelectUserModel(self, model_def):
msg = model_def.PackParams()
pg = self.m_params
pg.ClearPage(0)
#pg.Append(wxpg.PropertyCategory('Model properties'))
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)))
pg.SetPropertyClientData(pid, k)
pg.SetPropertyHelpString(pid, p.GetComment())
def OnModelActivated(self, event):
item = event.GetItem()
data = self.m_user_models.GetPyData(item)
self.SelectUserModel(data)
def OnParamChanging(self, event):
value = event.GetValue()
print repr(value)
#wx.MessageBox(value, 'changing')
#event.Veto()
def OnTest(self, event):
um = self.m_user_models
id = um.GetSelection()
md = um.GetItemPyData(id)
wx.MessageBox(md.PackParams())
md.Flush()
#wx.MessageBox('test')
def OnDuplicate(self, event):
um = self.m_user_models
id = um.GetSelection()
title = um.GetItemText(id)
parent = um.GetItemParent(id)
md = um.GetItemPyData(id)
child = um.AppendItem(parent, title + ' Copy')
um.SetPyData(child, md.Copy())
#-----------------------------------------------------------------------------
# Приложение
#-----------------------------------------------------------------------------
class ThisApp(wx.App):
def OnInit(self):
# Создание главного окна
frame = MainFrame()
self.SetTopWindow(frame)
frame.Show(True)
return True
#-----------------------------------------------------------------------------
# Запуск приложения
#-----------------------------------------------------------------------------
if __name__ == "__main__":
app = ThisApp(redirect = False)
app.MainLoop()

View File

@ -196,7 +196,7 @@ class Job:
self.result = data['result'] self.result = data['result']
# произошла ошибка # произошла ошибка
elif ans == 'error': elif ans == 'error':
WriteToLog('Error!') WriteToLog('Error! ' + msg)
# недокументированный ответ приложения # недокументированный ответ приложения
else: else:
pass pass
@ -243,17 +243,18 @@ class Job:
def IsFinished(self): def IsFinished(self):
return self.state == JOB_COMPLETED or self.state == JOB_STOPPED return self.state == JOB_COMPLETED or self.state == JOB_STOPPED
def IsComplete(self):
return self.GetStatus() == JOB_COMPLETE
def Stop(self): def Stop(self):
if self.proc and self.proc.poll() != None: WriteToLog('Try to kill')
if self.proc and self.proc.poll() == None:
self.proc.kill() self.proc.kill()
WriteToLog('Job killed') WriteToLog('Job killed')
def GetState(self): def GetState(self):
return self.state return self.state
def IsComplete(self):
return self.GetStatus() == JOB_COMPLETE
def GetResult(self): def GetResult(self):
return self.result return self.result

10
task.py
View File

@ -174,13 +174,17 @@ def main():
p = mdef2.PackParams() p = mdef2.PackParams()
pprint(p) pprint(p)
mdef.Flush() #mdef.Flush()
mdef2.Flush() mdef2.Flush()
time.sleep(3) time.sleep(1)
mdef2.job.Stop()
time.sleep(5)
print mdef2.job.GetState()
print 'RESULT' print 'RESULT'
pprint(mdef.job.result) #pprint(mdef.job.result)
pprint(mdef2.job.result) pprint(mdef2.job.result)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -17,12 +17,14 @@
"r": { "r": {
"type": "double", "type": "double",
"default": 6.28, "default": 6.28,
"title": "Right edge",
"comment": "Right edge" "comment": "Right edge"
}, },
"d": { "d": {
"type": "int", "type": "int",
"default": 5, "default": 5,
"title": "Serie deep",
"comment": "Number of members in taylor serie" "comment": "Number of members in taylor serie"
}, },

View File

@ -7,6 +7,7 @@
import sys import sys
import json import json
import time
def write(msg): def write(msg):
sys.stdout.write(str(msg) + '\n') sys.stdout.write(str(msg) + '\n')
@ -80,11 +81,12 @@ def main():
res.append([l, y]) res.append([l, y])
write(answer(round(l / r, 2))) write(answer(round(l / r, 2)))
l += h l += h
time.sleep(0.5)
write(result(res)) write(result(res))
except: except Exception, e:
write(error('Fatal error')) write(error('Fatal error: ' + str(e)))
sys.exit(1) sys.exit(1)
if __name__ == '__main__': if __name__ == '__main__':