centos6.2安装界面修改(2)

第2步

给安装界面添加背景图

centos6.2是用anaconda做的安装程序,主要部分都是使用python写的

分析anaconda程序的主要流程(只考虑GUI模式安装)

我没有另外下载anaconda的源代码,直接将centos6.2的安装光盘下 images/install.img解压,得到源代码(python部分)

我所做的所有修改也都是在这个代码的基础上修改的

路径是以install.img解压后的根目录为根目录

主程序

/usr/bin/anaconda
  class Anaconda:
  
  if if __name__ == "__main__":   #入口
   anaconda=Anaconda()
   ...
   主要是初始化安装环境和anaconda的值
   ...
   try:
      anaconda.intf.run(anaconda)   //开始安装
   except SystemExit, code:
      anaconda.intf.shutdown()
    
  intf的值呢?---->在前面class Anaconda中的setInstallInterface函数中赋值的
  函数如下:
  
  def setInstallInterface(self, display_mode):
        # setup links required by graphical mode if installing and verify display mode
        if display_mode == 'g':
            stdoutLog.info (_("Starting graphical installation."))

            try:
                from gui import InstallInterface    #GUI模式
            except Exception, e:
                stdoutLog.error("Exception starting GUI installer: %s" %(e,))
                # if we're not going to really go into GUI mode, we need to get
                # back to vc1 where the text install is going to pop up.
                if not x_already_set:
                    isys.vtActivate (1)
                stdoutLog.warning("GUI installer startup failed, falling back to text mode.")
                display_mode = 't'
                if 'DISPLAY' in os.environ.keys():
                    del os.environ['DISPLAY']
                time.sleep(2)

        if display_mode == 't':
            from text import InstallInterface
            if not os.environ.has_key("LANG"):
                os.environ["LANG"] = "en_US.UTF-8"

        if display_mode == 'c':
            from cmdline import InstallInterface

        self.intf = InstallInterface()  #GUI模式下intf的值就是通过gui.py/InstallInterface()得到的
  
  开始安装
   try:
    anaconda.intf.run(anaconda) #实际上的开始安装动作
   except SystemExit, code:
    anaconda.intf.shutdown()
    ......
   

 

  是根据显示模式选择不同的安装类,在图形模式下就是
  from gui import InstallInterface
  self.intf = InstallInterface()
  
  找到gui.py中的InstallInterface类
  找到InstallInterface的run函数
  
  

def run(self, anaconda):
   self.anaconda = anaconda   #前面anaconda设置的资源和配置都可以用了

   # XXX x_already_set is a hack
   if anaconda.id.keyboard and not anaconda.id.x_already_set:
    anaconda.id.keyboard.activate()

   self.icw = InstallControlWindow (self.anaconda)   #注意真正执行者来了
   self.icw.run ()

 

  
  InstallControlWindow()这个类才是真正干实事的
  
  看看InstallControlWindow.run()
  

def run(self):
   self.setup_window()
   gtk.main()

再看看setup_window()干了些什么事

def setup_window (self):
        self.setLtR()

        self.loadGlade()
        self.window = self.mainxml.get_widget("mainWindow")
        self.window.connect("delete_event", self.delwin_event)
        self.createWidgets()
        self.connectSignals()
        self.setScreen()
        self.window.show()
        # calling present() will focus the window in the winodw manager so
        # the mnemonics work without additional clicking
        self.window.present()

从命名我们就可以知道这个函数就只在创建窗体,和子控件,设置事件处理函数等
再看这里面的这个函数比较特殊setScreen()

def setScreen (self):
        (step, anaconda) = self.anaconda.dispatch.currentStep()
        if step is None:
            gtk.main_quit()
            return

        if not stepToClass[step]:
            if self.anaconda.dispatch.dir == DISPATCH_FORWARD:
                return self.nextClicked()
            else:
                return self.prevClicked()

        (file, className) = stepToClass[step]
        newScreenClass = None

        while True:
            try:
                found = imputil.imp.find_module(file)
                loaded = imputil.imp.load_module(className, found[0], found[1],
                                                 found[2])
                newScreenClass = loaded.__dict__[className]
                break
            except ImportError, e:
                print(e)
                win = MessageWindow(_("Error!"),
                                    _("An error occurred when attempting "
                                      "to load an installer interface "
                                      "component.\n\nclassName = %s")
                                    % (className,),
                                    type="custom", custom_icon="warning",
                                    custom_buttons=[_("_Exit"),
                                                    _("_Retry")])
                if not win.getrc():
                    msg =  _("The system will now reboot.")
                    buttons = [_("_Reboot")]

                    MessageWindow(_("Exiting"),
                                  msg,
                                  type="custom",
                                  custom_icon="warning",
                                  custom_buttons=buttons)
                    sys.exit(0)

        ics = InstallControlState (self)
        ics.setPrevEnabled(self.anaconda.dispatch.canGoBack())
        self.destroyCurrentWindow()
        self.currentWindow = newScreenClass(ics)

        new_screen = self.currentWindow.getScreen(anaconda)

        # If the getScreen method returned None, that means the screen did not
        # want to be displayed for some reason and we should skip to the next
        # step.  However, we do not want to remove the current step from the
        # list as later events may cause the screen to be displayed.
        if not new_screen:
            if self.anaconda.dispatch.dir == DISPATCH_FORWARD:
                self.anaconda.dispatch.gotoNext()
            else:
                self.anaconda.dispatch.gotoPrev()

            return self.setScreen()

        self.update (ics)

        self.installFrame.add(new_screen)
        self.installFrame.show_all()

        self.handle = gobject.idle_add(self.handleRenderCallback)

        if self.reloadRcQueued:
            self.window.reset_rc_styles()
            self.reloadRcQueued = 0

看这个代码大致可以知道anaconda安装过程中窗体的处理流程
与一般windows中处理窗体的方法不同,anaconda只有一个窗体,就是self.window, 每个步骤需要显示的控件都是放置在这个窗体上的(放在self.installFrame中),执行到每个步骤,都是将上一步骤的控件删掉,再添加这个步骤的控件

我们要给安装界面添加背景图实际上只需要给 self.window添加上背景图就可以了

可以在setup_window()函数中修改

修改后的函数

def setup_window (self):
        self.setLtR()

        self.loadGlade()
        self.window = self.mainxml.get_widget("mainWindow")
        self.window.connect("delete_event", self.delwin_event)
        self.createWidgets()
        self.connectSignals()
        self.window.realize()
        screen=gtk.gdk.screen_get_default()
        width = screen.get_width()
        height = screen.get_height()
        import math
        img = findPixmap("bg.png")
        pixBuf=gtk.gdk.pixbuf_new_from_file(img)
        pixBuf=pixBuf.scale_simple(width,height,gtk.gdk.INTERP_HYPER)
        pixMap=pixBuf.render_pixmap_and_mask()
        gdkWin = self.window.get_window()
        gdkWin.set_back_pixmap(pixMap[0], False)
        self.setScreen()
        self.window.show()
        # calling present() will focus the window in the winodw manager so
        # the mnemonics work without additional clicking
        self.window.present()

就是设置一张图片作为窗体背景
有个问题需要注意的就是,图片必须拉伸到和窗体的大小一样,否则会是平铺的效果,和windows桌面背景选择一张图平铺一样

这个问题找了半天时间pygtk的资料不好找啊````````最后还是看别人的gtk的例子,再根据函数名找对应的pygtk资料.


  

posted @ 2013-01-07 18:06  sjun  阅读(1014)  评论(1编辑  收藏  举报