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资料.