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