lovesnow
2013-03-14 06:16 deepin
上面程序没有实现层叠的效果 , 可拉伸, 每个小窗口里可以放任意gtk容器或控件,
看看这个
深度截图20130313222002.png
Copy the Code
看看这个
深度截图20130313222002.png
- import gtk, gobject
- import sys
- _print = lambda *args: None
- _print = lambda *args: sys.stdout.write(' '.join([str(i) for i in args]) + '\n')
- try: import i18n
- except: from gettext import gettext as _
- class GtkMdiTabbar(gtk.Notebook):
- homogeneous_tabs = False
- def __init__(self):
- self.__gobject_init__()
- self.set_scrollable(True)
- self.popup_enable()
- self.set_homogeneous_tabs(self.homogeneous_tabs)
- self.unset_flags(gtk.CAN_FOCUS)
- ##
- self._is_action_jn = False
- ##
- #self.connect("grab-focus", self.on_focus)
- #self.connect("focus-tab", self.on_focus_tab)
- self.connect("create-window", self.on_create_window)
- self.connect("page-reordered", self.on_page_reordered)
- self.connect("change-current-page", self.on_change_current_page)
- self.connect("select-page", self.on_select_page)
- self.connect("switch-page", self.on_switch_page)
- pass
- def add(self, child):
- p = gtk.EventBox()
- child.tab = p
- p.p = child
- label = gtk.Label(child.title)
- self.append_page(p, label)
- self.set_tab_detachable(p, True)
- self.show_all()
- pass
- def action_tab(self, child):
- n = self.page_num(child.tab)
- self._is_action_jn = True
- self.set_current_page(n)
- pass
- def get_child_by_n(self, n):
- p = self.get_nth_page(n)
- if p:
- return p.p
- return
- def get_n_by_child(self, child):
- return self.page_num(child.tab)
- def on_focus_tab(self, widget, *args):
- _print('on_focus_tab:', widget, args)
- pass
- def remove(self, child):
- p = self.page_num(child.tab)
- if p:
- self.remove_page(p)
- pass
- pass
- def on_focus(self, *args):
- _print('on_focus:', args)
- pass
- def on_create_window(self, page, x, y, *args):
- # when a detachable tab is dropped on the root window.
- _print('on_create_window:', page, x, y, args)
- pass
- def on_page_reordered(self, widget, child, page_num, *args):
- _print('on_page_reordered:', widget, child, page_num, args)
- pass
- def on_change_current_page(self, widget, offset, *args):
- _print('on_change_current_page:', widget, offset, args)
- pass
- def on_switch_page(self, widget, page, page_num, *args):
- if self._is_action_jn:
- self._is_action_jn = False
- return
- _print('on_switch_page:', widget, page, page_num, args)
- self.get_nth_page(page_num).p.action()
- pass
- def on_select_page(self, widget, move_focus, *args):
- _print('on_select_page:', widget, move_focus, args)
- pass
- class GtkMdiWindow(gtk.EventBox):
- __gtype_name__ = 'GtkMdiWindow'
- __gsignals__ = {
- 'switch': (gobject.SIGNAL_RUN_LAST, None, ()),
- }
- bg_title = gtk.gdk.Color('#377F0C')
- fg_title = gtk.gdk.Color('#ffffff')
- defalut_max = False
- def __init__(self, child=gtk.Alignment(), title="", icon=None,
- skiptaskbar=False):
- self.__gobject_init__()
- self.title = title
- self.icon = icon
- self._is_in_move = False
- self._is_in_resize_rb = False
- self._is_max = False
- self._is_min = False
- ##
- self._old_x = 0
- self._old_y = 0
- self.modify_bg(gtk.STATE_NORMAL, self.bg_title)
- ##
- self._child = child
- self.child_focus = child.child_focus
- self.child_get = child.child_get
- self.child_get_property = child.child_get_property
- self.child_notify = child.child_notify
- self.children = child.children
- self.child_set = child.child_set
- self.child_set_property = child.child_set_property
- self.child_type = child.child_type
- ##
- self.unset_flags(gtk.CAN_FOCUS)
- self.connect("set_focus_child", self.on_focus)
- self.connect("grab_focus", self.on_focus)
- ## move, resize
- self.connect("event", self.on_title_event)
- ##
- self.vbox1 = gtk.VBox(False, 0)
- ## MDI Window Border
- self.vbox1.set_border_width(3)
- #self.vbox1.connect("set_focus_child", self.on_focus)
- #self.vbox1.connect("grab_focus", self.on_focus)
- #self.vbox1.connect("expose_event", self.on_focus)
- #self.vbox1.connect("focus", self.on_focus)
- ## simulate MDI Window Title
- self.titlebar = gtk.HBox(False, 0)
- self.titlebar.unset_flags(gtk.CAN_FOCUS)
- self.titlebar.show()
- self.icon_label = gtk.Label("")
- self.icon_label.modify_fg(gtk.STATE_NORMAL, self.fg_title)
- self.icon_label.set_padding(5, 0)
- self.icon_label.set_markup("v")
- self.icon_label.show()
- ##
- eventbox = gtk.EventBox()
- eventbox.modify_bg(gtk.STATE_NORMAL, self.bg_title)
- eventbox.connect("button_release_event", self.on_icon)
- eventbox.add(self.icon_label)
- self.titlebar.pack_start(eventbox, False, False, 0)
- self.title_label = gtk.Label(title)
- self.title_label.set_padding(10, 0)
- self.title_label.modify_fg(gtk.STATE_NORMAL, self.fg_title)
- self.title_label.show()
- self.titlebar.pack_start(self.title_label)
- ## min, max, close button
- self.min_label = gtk.Label("")
- self.min_label.modify_fg(gtk.STATE_NORMAL, self.fg_title)
- self.min_label.set_padding(5, 0)
- self.min_label.set_tooltip_markup(_("Iconify Window"))
- self.min_label.set_markup("_")
- self.min_label.show()
- ##
- eventbox = gtk.EventBox()
- eventbox.modify_bg(gtk.STATE_NORMAL, self.bg_title)
- eventbox.connect("button_press_event", self.on_min)
- eventbox.add(self.min_label)
- self.titlebar.pack_start(eventbox, False, False, 0)
- self.max_label = gtk.Label("")
- self.max_label.modify_fg(gtk.STATE_NORMAL, self.fg_title)
- self.max_label.set_padding(5, 0)
- self.max_label.set_tooltip_markup(_("Maximize Window"))
- self.max_label.set_markup("+")
- self.max_label.show()
- ##
- eventbox = gtk.EventBox()
- eventbox.modify_bg(gtk.STATE_NORMAL, self.bg_title)
- eventbox.connect("button_release_event", self.on_max)
- eventbox.add(self.max_label)
- self.titlebar.pack_start(eventbox, False, False, 0)
- self.close_label = gtk.Label("")
- self.close_label.modify_fg(gtk.STATE_NORMAL, self.fg_title)
- self.close_label.modify_bg(gtk.STATE_NORMAL, self.bg_title)
- self.close_label.set_padding(5, 0)
- self.close_label.set_tooltip_markup(_("Close Window"))
- self.close_label.set_markup("x")
- self.close_label.show()
- ##
- eventbox = gtk.EventBox()
- eventbox.modify_bg(gtk.STATE_NORMAL, self.bg_title)
- eventbox.connect("button_release_event", self.on_close)
- eventbox.add(self.close_label)
- self.titlebar.pack_start(eventbox, False, False, 0)
- self.vbox1.pack_start(self.titlebar, False, False, 0)
- ## MDI Window Area
- #self.mdi_alignment = gtk.Alignment(0.5, 0.5, 0, 0)
- #self.mdi_alignment.show()
- #self.vbox1.pack_start(self.mdi_alignment)
- self._child_box = gtk.EventBox()
- self._child_box.add(self._child)
- self.vbox1.pack_start(self._child_box, True, True, 0)
- ##
- self.add(self.vbox1)
- self.show_all()
- pass
- def _raise(self, *args):
- try:
- window = self.get_window() or self.get_window(1)
- if window:
- gtk.gdk.Window.raise_(window)
- self.emit("switch", )
- pass
- pass
- except:
- pass
- pass
- def lower(self, *args):
- try:
- window = self.get_window() or self.get_window(1)
- if window:
- gtk.gdk.Window.lower(window)
- pass
- pass
- except:
- pass
- pass
- def action(self):
- _print('action:', self)
- if self._is_min:
- self.unmax()
- pass
- self._raise()
- self._child.grab_focus()
- pass
- def on_focus(self, widget, *args):
- _print('on_focus:', widget, args)
- self._raise()
- if widget and 'mditabbar' in self.parent.parent.__dict__:
- mditabbar = self.parent.parent.mditabbar
- mditabbar.action_tab(self)
- pass
- pass
- def on_title_event(self, widget, event):
- #_print('on_title_event', widget, event)
- # for move
- if event.type == gtk.gdk.BUTTON_PRESS:
- if event.button == 3:
- self.on_menu(widget, event)
- return
- else:
- self.on_focus(self)
- self._child.grab_focus()
- self._px, self._py = self.parent.get_pointer()
- ## MdiWindow x, y
- self._wx, self._wy = self.get_window().get_position()
- ## MdiArea width, height
- i, t, self._aw, self._ah = self.parent.get_allocation()
- ## MdiWindow width, height
- i, t, self._w, self._h = self.get_allocation()
- ##
- self._ox = self._wx - self._px
- self._oy = self._wy - self._py
- if self._w - event.x < 20 and self._h - event.y < 20:
- self._is_in_resize_rb = True
- pass
- else:
- self._is_in_move = True
- pass
- return
- return
- elif event.type == gtk.gdk.BUTTON_RELEASE:
- self._is_in_move = False
- self._is_in_resize_rb = False
- return
- ## move MdiWindow
- elif self._is_in_move and event.type == gtk.gdk.MOTION_NOTIFY:
- px, py = self.parent.get_pointer()
- if px < 5: px = 5
- if py < 0: py = 0
- if px > self._aw: px = self._aw
- if py > self._ah: py = self._ah
- mx = px + self._ox
- my = py + self._oy
- #self.move(mx, my)
- self.parent.move(self, mx, my)
- return
- ## resize MdiWindow
- elif self._is_in_resize_rb and event.type == gtk.gdk.MOTION_NOTIFY:
- x, y = event.x, event.y
- px, py = self.parent.get_pointer()
- if x < 30: x = 30
- if y < 30: y = 30
- if px > self._aw: x = self.get_allocation()[2]
- if py > self._ah: y = self.get_allocation()[3]
- self.set_size_request(int(x), int(y))
- return
- pass
- def on_menu(self, widget, event):
- _print('on_menu:', widget, event)
- pass
- def on_icon(self, widget, event):
- if event.button == 1:
- _print('on_icon:', widget, event)
- pass
- def on_min(self, widget, event):
- if event.button == 1:
- _print('on_min:', widget, event)
- self.min()
- pass
- def on_unmax(self, widget, event):
- if event.button != 1: return
- _print('on_unmax:', widget, event)
- self.unmax()
- def on_max(self, widget, event):
- if event.button != 1: return
- self.max()
- pass
- def on_close(self, widget, event):
- if event.button == 1:
- _print('on_close:', widget, event)
- self.close()
- pass
- pass
- def move(self, x, y):
- _print('move:', x, y)
- self.parent.move(self, x, y)
- pass
- def min(self, *args):
- self._is_min = True
- # save MdiWindow position x, y
- self._old_wx, self._old_wy = self.get_window().get_position()
- # save MdiWindow width, height
- i, t, self._old_w, self._old_h = self.get_allocation()
- self.parent.grab_focus()
- #self.lower()
- self.hide()
- if 'mditabbar' in self.parent.parent.__dict__:
- mditabbar = self.parent.parent.mditabbar
- mditabbar.next_page()
- pass
- pass
- def max(self, *args):
- i, t, self._w, self._h = self.get_allocation()
- i, t, self._aw, self._ah = self.parent.get_allocation()
- if self._w < self._aw or self._h < self._ah:
- self._is_max = False
- pass
- if self._is_max: return self.unmax()
- ##
- self._is_max = True
- self._is_min = False
- # save MdiWindow position x, y
- self._old_wx, self._old_wy = self.get_window().get_position()
- # save MdiWindow width, height
- i, t, self._old_w, self._old_h = self.get_allocation()
- self.move(0, 0)
- self.set_size_request(self._aw, self._ah)
- pass
- def unmax(self, *args):
- self._is_max = False
- self._is_min = False
- self.set_size_request(self._old_w, self._old_h)
- self.move(self._old_wx, self._old_wy)
- self.show_all()
- pass
- def close(self, *args):
- if 'mditabbar' in self.parent.parent.__dict__:
- mditabbar = self.parent.parent.mditabbar
- mditabbar.remove(self)
- pass
- self.destroy()
- pass
- class GtkMdiArea(gtk.Layout):
- __gtype_name__ = 'GtkMdiArea'
- __gsignals__ = {
- 'switch-window': (gobject.SIGNAL_RUN_LAST, None, (gtk.Widget,)),
- }
- need_resize = 1L
- def __init__(self):
- self.__gobject_init__()
- #self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color("#003300"))
- self._old_w = 0
- self._old_h = 0
- self.unset_flags(gtk.CAN_FOCUS)
- self.connect("size-allocate", self.on_resize)
- pass
- def add(self, mdiwindow, x=0, y=0):
- gtk.Layout.put(self, mdiwindow, x, y)
- mdiwindow.connect("switch", self.on_switch)
- pass
- def on_resize(self, widget, rectangle):
- i, t, w, h = rectangle
- if self._old_w == w and self._old_h == h:
- return
- _print('on_resize:', widget, rectangle)
- self._old_w, self._old_h = w, h
- for p in self.children():
- if p._is_max:
- p.set_size_request(w, h)
- pass
- pass
- pass
- def on_switch(self, widget, *args):
- _print('on_switch', self, widget, args)
- self.emit("switch-window", widget)
- if 'mditabbar' in self.parent.__dict__:
- mditabbar = self.parent.mditabbar
- mditabbar.action_tab(widget)
- pass
- pass
- class GtkMdi(gtk.Table):
- def __init__(self):
- self.__gobject_init__()
- self.mdiarea = GtkMdiArea()
- self.mditabbar = GtkMdiTabbar()
- ## table.attach(widget, left_attach=0, right_attach=1, top_attach=0,
- #bottom_attach=1)
- self.attach(self.mditabbar, 0, 1, 0, 1, gtk.FILL, gtk.FILL, 0, 0)
- self.attach(self.mdiarea, 0, 1, 1, 2)
- pass
- def set_tab_pos(self, pos):
- # pos: 0: left, 1: right, 2: top, 3: bottom
- pass
- def add(self, mdiwindow, x=0, y=0):
- self.mdiarea.add(mdiwindow, x, y)
- self.mditabbar.add(mdiwindow)
- pass
- def tab_top(self, *args):
- pass
- def _demo():
- _print('main')
- w = gtk.Window()
- w.set_title("Test MDI")
- w.set_default_size(500, 500)
- mdi = GtkMdi()
- ##
- ts = gtk.ScrolledWindow()
- ts.add(gtk.TextView())
- ts.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- ts.set_size_request(150, 150)
- mw = GtkMdiWindow(ts, 'MDI Document 1')
- mdi.add(mw, 0, 0)
- ##
- ts = gtk.ScrolledWindow()
- ts.add(gtk.TextView())
- ts.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- ts.set_size_request(150, 150)
- mw = GtkMdiWindow(ts, 'MDI Document 2')
- mdi.add(mw, 30, 30)
- ##
- ts = gtk.ScrolledWindow()
- ts.add(gtk.TextView())
- ts.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- ts.set_size_request(150, 150)
- mw = GtkMdiWindow(ts, 'MDI Document 3')
- mdi.add(mw, 60, 60)
- w.add(mdi)
- w.show_all()
- w.connect('delete-event', gtk.main_quit)
- gtk.main()
- if __name__=="__main__":
- _demo()
Reply Like 0 View the author
现在这个模拟环境:
将这个 pygtk window想象成一个桌面环境或者一个浏览器吧 又或者想象成一个裸机, 只提供了一些实模式的绘制函数.. ...
里面的一个个矩形就是窗体.
中间的小红点模拟的是窗体内的button.
你点击运动一下.
模拟器的好处就是可以模拟一切, 解释脚本, 生成你想要的效果. nes模拟器也是要分析nes文件,然后根据模拟环境: CPU, , 等等来运行nes. 好处不多说, 看bochs等等就知道,模拟技术的强大, 本人不懂,就是随便玩玩.
可以模拟窗口的栈效果,还有向绘制端发送消息,告诉它 绘制那个窗口, 窗口要多大, 在什么位置等等一些东西.
昨天晚上太无聊,花了十多分钟写一个简单的demo测试一下. 详情可以看安卓的窗口管理器分析.
复制代码, 运行看看.