2007年09月24日

I’v written an article about how to use layout, and you can find it at here.

And I also made a Source code and Screenshots gallery wiki page, so you can share your UI source code and screenshot with others. You can visit the page here.

For now, there is a simplest example:

And the code is:

#You can create a gallery folder under meide project so that sys.path.insert(0, ‘..’) can find the meide module.

import wx
import sys

sys.path.insert(0, ‘..’)

class wxApp(wx.App):
    def OnInit(self):
        return True

class Frame(wx.Frame):
    def __init__(self):
        super(Frame, self).__init__(None, -1)
        self.init()
       
    def init(self):
        import meide as ui
       
        self.box = box = ui.VBox()
        box.add(ui.Button(‘Hello’), flag=wx.ALIGN_CENTER)
       
        ui.create(self, box, fit=2)
       
if __name__ == ‘__main__’:
    wxApp = wxApp(0)
    frame = Frame()
    frame.Show()
    wxApp.SetTopWindow(frame)
    wxApp.MainLoop()

2007年09月21日

I’v finished the refactor of Find & Replace Dialog, now Find and
Replace is a panel and will appear at the bottom of document area. The
key binding is not changed. Hope you like it.

You can open it just press Ctrl+F(Find) or Ctrl+H(Find and Replace),
you should know the shortcuts will be enabled only when the focus is
in a document. And you can swith between Find and Find & Replace, just
click the Open Replcae image button which is next to Close image
button.

2007年09月18日

I’v created a project db-dump on code.google.com, you can visit it at: http://code.google.com/p/db-dump/

And db_dump.py is used for dump and restore database of django. And it can also support some simple situations for Model changes, so it can also be used in importing data after the migration of Model.

So if you like it or want to try it, you can download it from http://db-dump.googlecode.com/files/db_dump2.1.zip

And if you have any idea about it just write a issue or send me an email, I’ll try my best to change it.

If you want to run it, just extract it to project directory, you should put it with the settings.py together, and run it according to the document of the project site.

2007年09月17日

meide supports two kinds of creation fashions. One way I called "Lazy Creation", that means you create a layout first, and don’t create the underlying wx widgets, till you invoke module function create() method. At this time, all the real underlying wx widgets will be created. For example:

 import meide as ui
    
 self.box = box = ui.VBox()
 btn = box.add(ui.Button(‘Hello’), flag=wx.ALIGN_CENTER|wx.ALL)
 btn.bind(‘click’, self.OnClickHello)

 ui.create(self, box, fit=2)

For lazy creation, event binding also be lazy creation.

The other way I called "Immediately Creation", that means you create a wrap layout object then invoke its create() method, then the underlying wx sizer object will be created. Then you add other element, but this time the underlying element will be also created immediately, so you don’t need to invoke module function create() any more. For example:

import meide as ui

self.box = box = ui.VBox().create(self).auto_layout()
btn = box.add(ui.Button(‘Hello’), flag=wx.ALIGN_CENTER|wx.ALL)
btn.bind(‘click’, self.OnClickHello)
box.auto_fit(2)

This time the event binding is also immediately. The create(win) method of a layout object only create the underlying wx widgets, so if you want to set the sizer to the window object and set auto layout you can invoke auto_layout() method. And at the end of creation, you may want to invoke auto_fit(fit) to resize the window.

Below is recently updates since (08/28):

  1. Add script and shell commands shortcut binding. For scripts you can bind shortcuts from Ctrl+0 to Ctrl+9, and for shell commands you can bind shortcuts from Alt+0 to Alt+9.
  2. Update pyflakes module to trunk version
  3. Change Find in Files Dialog to Panel, and using thread to do the process, it’s a big change I think
  4. Improve preference dialog creation with meide module
  5. Add a new option to control whether showing the docstring when you navigating in class browser window
  6. If save file failed, then invoke save as, and don’t create a tmp first, but save the file directly

Bugs fix:

  1. Fix adding empty directory to directory browser window bug
  2. Fix open un-exists file will popup two message dialog bug
  3. Fix directory browser refresh bug
  4. Fix directory browser insert node bug
  5. Fix shortcuts from 1-based bug
2007年09月08日

Here is a dialog code which I want to get a filename:

import wx

class MyFileEntry(wx.Dialog):    def __init__(self, parent, title, message, defaultvalue):        wx.Dialog.__init__(self, parent, -1, style = wx.DEFAULT_DIALOG_STYLE, title = title)

        box = wx.BoxSizer(wx.VERTICAL)        stext = wx.StaticText(self, -1, label=message)        box.Add(stext, 0, wx.ALIGN_LEFT|wx.ALL, 5)        box1 = wx.BoxSizer(wx.HORIZONTAL)        self.text = wx.TextCtrl(self, -1, defaultvalue)        self.text.SetSelection(-1, -1)        box1.Add(self.text, 1, wx.EXPAND|wx.ALL, 5)        self.ID_BROWSER = wx.NewId()        self.btnBrowser = wx.Button(self, self.ID_BROWSER, tr("Browser"), size=(50, -1))        box1.Add(self.btnBrowser, 0, wx.ALL, 5)        box.Add(box1, 1, wx.EXPAND, 5)        box2 = wx.BoxSizer(wx.HORIZONTAL)        btnOK = wx.Button(self, wx.ID_OK, tr("OK"))        btnOK.SetDefault()        box2.Add(btnOK, 0, wx.ALIGN_RIGHT|wx.RIGHT, 5)        btnCancel = wx.Button(self, wx.ID_CANCEL, tr("Cancel"))        box2.Add(btnCancel, 0, wx.ALIGN_LEFT|wx.LEFT, 5)        box.Add(box2, 0, wx.ALIGN_CENTER|wx.BOTTOM, 5)

        wx.EVT_BUTTON(self.btnBrowser, self.ID_BROWSER, self.OnBrowser)

        self.SetSizer(box)        self.SetAutoLayout(True)        box.Fit(self)

        self.value = defaultvalue

    def GetValue(self):        return self.text.GetValue()

    def OnBrowser(self, event):        dlg = wx.FileDialog(self, tr("Select A File"), "", "", tr("All file (*.*)|*.*"), wx.OPEN|wx.HIDE_READONLY)        if dlg.ShowModal() == wx.ID_OK:            filename = dlg.GetPath()            self.text.SetValue('%s' % filename)

Even if the code is very simple, but the code is very tedious. And now I change it with meide:

import meide as ui

class MyFileEntry(ui.SimpleDialog):    def __init__(self, parent, title, message, defaultvalue, fit=1):        box = ui.SimpleGrid()        box.add(message, ui.OpenFile(defaultvalue), name='filename')        super(MyFileEntry, self).__init__(parent, box, title, fit=fit, size=(400, -1))

    def GetValue(self):        return self.layout.GetValue()['filename']

The MyFileEntry inherits from SimpleDialog, so it’ll automatically create a Ok and Cancel buttons for you.

The main improvement is:

* add validate, you can see the example in test_validate.py

I also add many comments in source code and examples, so if you like
you can read them.

Hope you enjoy it. And I think I’v finished all the goals that I
design it originally. If you have good ideas and bugs report please
send me an email.

Download http://meide.googlecode.com/files/meide-0.0.3.zip

2007年09月07日

Changes:

1. All contents are packaged together.
2. Add test_custom.py example to show how to use meide with custom widget.
3. Add many and many comments in the meide.py source code.

Download link: http://meide.googlecode.com/files/meide-0.0.2.zip

2007年09月06日

What is meide

meide is a ui interface creation library. You can use it to create wxPython based user interface. It can deal with several sizer class, for example: BoxSizer, GridBagSizer, StaticBoxSizer, and it also provide an easy way to create widgets, like: StaticText, TextCtrl, CheckBox, etc. You know create ui interface manually is a hard work, and that’s why meide comes out.

What is the goals of meide

  1. Supports easily sizer creation
  2. Supports easily widgets creation
  3. Supports easily frame creation, like: Dialog, Panel, etc
  4. Supports SetValue and GetValue to value-field
  5. Supports event binding
  6. Supports validate
  7. Makes above as easy as I can

meide is still in heavy developpint, so please keep touch with it, maybe you can find something very useful or helpful.

How to use it

The step is easy:

  1. Creatint a layout
  2. Add widgets or sub-layout
  3. Binding event
  4. invoke the create method

Examples

There are some testing examples you can find in tests subdirectroy.

Example 1 – The simplest example

This example comes from test/test_simple.py, you can run all the examples in the tests directory. And below is just the main code snippet:

    import meide as ui

    self.box = box = ui.VBox()
    box.add(ui.Button('Hello'), flag=wx.ALIGN_CENTER|wx.ALL).bind('click', self.OnClickHello)

    ui.create(self, box, fit=2)

first, you shuld import meide module, you can rename it a new name ui.

`ui.VBox()’ will create a layout. So you can guess there should be a HBox, yes, you are right.

box.add will add widgets or sub-layout to current layout. For the most simplest case, you can only add widgets or sub-layout instance or even class name. For example:

    box.add(ui.Button)

this code is also right. The full add method signature is::

    def add(element, name='', proportion=None, flag=None, border=None)

So the first parameter should be a class name or instance of a widget or a layout. Other parameters could be skipped. Every element could has a name, and you can get this element back in the later via this name. If you don’t give a name, meide will automatically create one name for you, the name format will be like ‘id%d’, here the %d will automatically increase. proportion just like the proportion parameter of add method in any sizer class. and the flag and border are also the same. For more detail you can read the document of wx.Sizer Add method.

So the above example uses a flag parameter, and it means that the Hello button should be aligned center and four direction will have a border.

The next .bind will bind a click event to a function. meide will define some easily remembered event name, for example: click for EVT_BUTTON, check for EVT_CHECKBOX. So you can use these simple event name or just use EVT_CHECKBOX, meide will still deal with them. So bind('click', self.OnClickHello) means that when you click on the Hello button, it’ll raise a click event, and invoke self.OnClickHello function.

ui.create(self, box, fit=2) will initialize the layout. The first parameter is the parent window object. the second parameter is the layout object. And the third one is used to fit the window to the best size. If the fit is 0, don’t change the window size, if the fit is 1, then changes the height to the best size, if the fit is 2, then changes the width and height to the best size.

2007年09月03日

这是我新建的一个项目,主页在 http://code.google.com/p/meide/

背景:

使用wxPython开发GUI时经常要生成界面,
一种是通过工具生成(但我认为这种重用性并不好),另一种就是手工写代码。我主要是手工写代码,但是需要你有耐心。以前创建过叫
EasyGuider 的项目,它可以通过字典形式的数据结构快速生成界面,不过存在一些问题:格式固定,不支持事件。于是我从快速辅助手写代码的需求上创建了这个新项目。它适合用来生成简单,有规律的界面。从我个人的开发体会(UliPad),大量的界面工作并不是很复杂,但是生成组件,布局比较麻烦,因此就想从这里入手,考虑如何快速开发界面。

目标:

方便定义界面
支持事件
支持validate(考虑中)

因此这个项目是从代码级的复用和简化方面来考虑的。目前已经有一些基础代码,有兴趣的可以看一看。不过需要实现的功能还很多。大家有什么好的想法可以交流。

整个框架的设计分为几个层次:

元素
布局
窗体(还未实现)
辅助工具

常见的控件将有对应的类实现。布局目前已经支持HBox, VBox, HGroup, VGroup, Grid, SimpleGrid。布局对象之间可以嵌套。

举一个简单的例子说明使用(可以看tests/test_hbox.py)

import wx
import sys

sys.path.insert(0, ‘..’)

class wxApp(wx.App):
   def OnInit(self):
       return True

class Frame(wx.Frame):
   def __init__(self):
       super(Frame, self).__init__(None, -1)
       self.init()

   def init(self):
       import meide
       self.box = box = meide.VBox(padding=4)
       box.add(”, meide.Label(‘Hello’))
       box.add(‘text’, meide.Text(‘Hello’, size=(100, -1)))
       meide.create(self, box)

if __name__ == ‘__main__’:
   wxApp = wxApp(0)
   frame = Frame()
   frame.Show()
   wxApp.SetTopWindow(frame)
   wxApp.MainLoop()

这是一个VBox的示例。VBox在创建时可以设置一个padding的参数,它表示这个VBox与周围的空白间距为4个像素。

box.add(”, meide.Label(‘Hello’))
这行是加了一个标签。第一个参数是名字,如果不需要可以为”。不过meide会自动生成一个id_开头的名字,不过一般不用。Label将会使用wx.StaticText控件来生成。也就是说每一个meide的控件将对应一个实际或组合的wxPython控件。Label至少需要一个字符串参数。其实meide在处理控件时比较特殊,它是按照wxPython相应控件的构造参数来组织的,你其实可以根据相应的实际控件填入其它的参数。

box.add(‘text’, meide.Text(‘Hello’, size=(100, -1)))
这行是加入一个文本输入字符,对应于单选输入。第一个参数为它的名字。从这个例子你可以看到它多了一个size的参数。100表示宽度,-1表示不关心。那么meide在处理每个控件时会有一个缺省的缩放因子,对于Text它就是(-1,
0)(从meide.py中可以找到,它是一个类属性叫proportion)。当出现size时,这个缩放因子会与size进行比较,如果缩放因子的x,y的值为-1表示可以缩放,同时相应的size的值也为-1的话,就在相应的方向上进行缩放。如果没有size参数,则按照缩放因子来进行设置。所以很有趣。缩放因子用来控制在哪个方向上可以缩放,而size的定义可以取消某个方面的缩放。

在添加完元素之后,执行:meide.create(self, box),这样元素就画出来了,同时box对应的sizer自动与窗体相关联。

以上只是一个简单的示例,还有许多功能在开发中。

同时要指出,目前meide并不是一个完整的界面解决工具,它侧重于代码的局部。如果你想使用更抽象的mvc的方式,建议研究一下enthought的traits。