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月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.

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.

2006年08月15日

NewEdit 中,现在增加了一个 Ruler 的插件,当然这个插件还在完善中。它目前只对 TextEditor 起作用。当打开一个编辑窗口时,如果你选中了显示标尺的菜单,那么会在编辑窗口的顶部显示出一个标尺来,如果你选择隐藏菜单,则这个标尺又会消失。那么也就是说,控件是动态变化的。如何实现的呢?

panel = wx.Panel(self.top, -1)
document = TextEditor(panel, self.parent, self.filename, self.documenttype)
ruler = RulerCtrl(panel, show=False)
box = wx.BoxSizer(wx.VERTICAL)
box.Add(ruler, 0, wx.EXPAND)
box.Add(document, 1, wx.EXPAND)
panel.SetSizer(box)
panel.SetAutoLayout(True)

代码只是示例性的,不算复杂。其中在创建ruler对象时,show=False表示不显示。那么在 RulerCtrl 的初始化函数中处理不显示可以这样:

def __init__(self, parent):
    …
    if not show:
        self.Hide()

为了实现标尺的切换,在RulerCtrl中有一个show的方法:

def show(self, flag):
    if flag:
        self.Show()
        self.parent.GetSizer().Layout()
    else:
        self.Hide()
        self.parent.GetSizer().Layout()

可以看到,首先根据flag值来决定显示或隐藏,然后再调用父对象的Sizer的Layout()方法进行处理即可。

我想通过这种方法,你可以在 wxPython 作出一些控制显示/隐藏的功能来。

2006年02月28日

现在在 wxPython 的邮件列表中正在开始一个非常有意义的项目,那就是由SPE编辑器的作者Stani发起了几大 wxPython 的编辑器的作者一同开发一个新的编辑器的项目。有人建议是做成一个IDE,不管怎么样都行。已经包含了象SPE, NewEdit, DrPython, ActiveGrid, 等人员的加盟,还有其它相关的一些项目的作者,如一个UML模块的作者,Eric3的作者也在关注,还有Robin这位wxPython的大佬也在关注。讨论很热烈,目前基本的想法是先创建一个精巧,稳定的核心,然后展开。但具体的细节还要等创建项目之后,可能会有一个wiki进行讨论。

不过使用英文讨论真是很麻烦,看着费劲,写着费劲。不过到是可以认识不少人,还是不错。有兴趣的也请关注,这将是一个非常好的学习的机会。有这么多经验非富的人参与,前景还是不错。

2006年02月09日

以前发布 NewEdit 的exe版本之后发现在运行时,外观不象直接从源码运行是xp风格的,一直也没有太在意。今天在 wxPython 邮件列表中偶然发现了一个解决方法,可以看这里。这个文档是 wxPython 的 FAQ。方法很简单:

从 wiki 上将提供的一个 manifest 的xml代码拷贝到NewEdit.exe.manifest,然后把它放在 NewEdit 的安装目录下,再启动 NewEdit 就可以了。于是我将其一起放入 NewEdit 的代码中了,以后再生成 exe 时自动就打在一起了。

2006年01月20日

Ubuntu已经升级到了 5.10 ,但是一直没有怎么用,因为wxPython一直没有装好。不过还是想装一下试试。于是开始查资料。

文档:Ubuntu中文的快速指南

主要进行了:

1. 源的修改

deb http://ubuntu.cn99.com/ubuntu/ breezy main restricted universe multiverse
deb http://ubuntu.cn99.com/ubuntu/ breezy-updates main restricted universe multiverse
deb http://ubuntu.cn99.com/ubuntu/ breezy-security main restricted universe multiverse
deb http://ubuntu.cn99.com/ubuntu/ breezy-backports main restricted universe multiverse
deb http://ubuntu.cn99.com/ubuntu-cn/ breezy main restricted universe multiverse
deb http://ubuntu.cn99.com/backports/ breezy-extras main restricted universe multiverse

2.系统更新

sudo apt-get update

3.安装 python2.4-dev 包

sudo apt-get install python2.4-dev

不知道有没有用,反正是装了

4.安装 Python-wxgtk2.6

sudo apt-get install python-wxgtk2.6

不知道为什么改名字了

然后下载 NewEdit 解压后就可以运行了。

python NewEdit.py

NewEdit 的确还存在一些问题,看一看能否解决。