• wxpython笔记:应用骨架


    原文链接:wxPython 教程 (十一): wxPython 应用骨架

    在本节,我们将创建一些 wxPython 应用骨架 。样例脚本将只负责设计界面而非实现功能,目标是为了展示几款流行 GUI 界面如何用 wxPython 来完成。

    文件管理器

    我们将创建一个 叫做 File Hunter 的应用,它是一个文件管理器,界面模仿 Unix 系统的文件管理器 Krusader。如果我们双击 splitter 部件,File Hunter 将被分成同样宽度的两个部分,如果我们重新调整主窗口大小时也会发生同样的事。

    tutorial wxpython-jiaocheng

    #!/usr/bin/python
     
    import wx
    import os
    import time
     
     
    ID_BUTTON=100
    ID_EXIT=200
    ID_SPLITTER=300
     
    class MyListCtrl(wx.ListCtrl):
        def __init__(self, parent, id):
            wx.ListCtrl.__init__(self, parent, id, style=wx.LC_REPORT)
     
            files = os.listdir('.')
            images = ['images/empty.png', 'images/folder.png', 'images/source_py.png', 
            'images/image.png', 'images/pdf.png', 'images/up16.png']
     
            self.InsertColumn(0, 'Name')
            self.InsertColumn(1, 'Ext')
            self.InsertColumn(2, 'Size', wx.LIST_FORMAT_RIGHT)
            self.InsertColumn(3, 'Modified')
     
            self.SetColumnWidth(0, 220)
            self.SetColumnWidth(1, 70)
            self.SetColumnWidth(2, 100)
            self.SetColumnWidth(3, 420)
     
            self.il = wx.ImageList(16, 16)
            for i in images:
                self.il.Add(wx.Bitmap(i))
            self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
     
            j = 1
            self.InsertStringItem(0, '..')
            self.SetItemImage(0, 5)
     
            for i in files:
                (name, ext) = os.path.splitext(i)
                ex = ext[1:]
                size = os.path.getsize(i)
                sec = os.path.getmtime(i)
                self.InsertStringItem(j, name)
                self.SetStringItem(j, 1, ex)
                self.SetStringItem(j, 2, str(size) + ' B')
                self.SetStringItem(j, 3, time.strftime('%Y-%m-%d %H:%M', 
            time.localtime(sec)))
     
                if os.path.isdir(i):
                    self.SetItemImage(j, 1)
                elif ex == 'py':
                    self.SetItemImage(j, 2)
                elif ex == 'jpg':
                    self.SetItemImage(j, 3)
                elif ex == 'pdf':
                    self.SetItemImage(j, 4)
                else:
                    self.SetItemImage(j, 0)
     
                if (j % 2) == 0:
                    self.SetItemBackgroundColour(j, '#e6f1f5')
                j = j + 1
     
     
    class FileHunter(wx.Frame):
        def __init__(self, parent, id, title):
            wx.Frame.__init__(self, parent, -1, title)
     
            self.splitter = wx.SplitterWindow(self, ID_SPLITTER, style=wx.SP_BORDER)
            self.splitter.SetMinimumPaneSize(50)
     
            p1 = MyListCtrl(self.splitter, -1)
            p2 = MyListCtrl(self.splitter, -1)
            self.splitter.SplitVertically(p1, p2)
     
            self.Bind(wx.EVT_SIZE, self.OnSize)
            self.Bind(wx.EVT_SPLITTER_DCLICK, self.OnDoubleClick, id=ID_SPLITTER)
     
            filemenu= wx.Menu()
            filemenu.Append(ID_EXIT,"E&xit"," Terminate the program")
            editmenu = wx.Menu()
            netmenu = wx.Menu()
            showmenu = wx.Menu()
            configmenu = wx.Menu()
            helpmenu = wx.Menu()
     
            menuBar = wx.MenuBar()
            menuBar.Append(filemenu,"&File")
            menuBar.Append(editmenu, "&Edit")
            menuBar.Append(netmenu, "&Net")
            menuBar.Append(showmenu, "&Show")
            menuBar.Append(configmenu, "&Config")
            menuBar.Append(helpmenu, "&Help")
            self.SetMenuBar(menuBar)
            self.Bind(wx.EVT_MENU, self.OnExit, id=ID_EXIT)
     
            tb = self.CreateToolBar( wx.TB_HORIZONTAL | wx.NO_BORDER | 
            wx.TB_FLAT | wx.TB_TEXT)
            tb.AddSimpleTool(10, wx.Bitmap('images/previous.png'), 'Previous')
            tb.AddSimpleTool(20, wx.Bitmap('images/up.png'), 'Up one directory')
            tb.AddSimpleTool(30, wx.Bitmap('images/home.png'), 'Home')
            tb.AddSimpleTool(40, wx.Bitmap('images/refresh.png'), 'Refresh')
            tb.AddSeparator()
            tb.AddSimpleTool(50, wx.Bitmap('images/write.png'), 'Editor')
            tb.AddSimpleTool(60, wx.Bitmap('images/terminal.png'), 'Terminal')
            tb.AddSeparator()
            tb.AddSimpleTool(70, wx.Bitmap('images/help.png'), 'Help')
            tb.Realize()
     
            self.sizer2 = wx.BoxSizer(wx.HORIZONTAL)
     
            button1 = wx.Button(self, ID_BUTTON + 1, "F3 View")
            button2 = wx.Button(self, ID_BUTTON + 2, "F4 Edit")
            button3 = wx.Button(self, ID_BUTTON + 3, "F5 Copy")
            button4 = wx.Button(self, ID_BUTTON + 4, "F6 Move")
            button5 = wx.Button(self, ID_BUTTON + 5, "F7 Mkdir")
            button6 = wx.Button(self, ID_BUTTON + 6, "F8 Delete")
            button7 = wx.Button(self, ID_BUTTON + 7, "F9 Rename")
            button8 = wx.Button(self, ID_EXIT, "F10 Quit")
     
            self.sizer2.Add(button1, 1, wx.EXPAND)
            self.sizer2.Add(button2, 1, wx.EXPAND)
            self.sizer2.Add(button3, 1, wx.EXPAND)
            self.sizer2.Add(button4, 1, wx.EXPAND)
            self.sizer2.Add(button5, 1, wx.EXPAND)
            self.sizer2.Add(button6, 1, wx.EXPAND)
            self.sizer2.Add(button7, 1, wx.EXPAND)
            self.sizer2.Add(button8, 1, wx.EXPAND)
     
            self.Bind(wx.EVT_BUTTON, self.OnExit, id=ID_EXIT)
     
            self.sizer = wx.BoxSizer(wx.VERTICAL)
            self.sizer.Add(self.splitter,1,wx.EXPAND)
            self.sizer.Add(self.sizer2,0,wx.EXPAND)
            self.SetSizer(self.sizer)
     
            size = wx.DisplaySize()
            self.SetSize(size)
     
            self.sb = self.CreateStatusBar()
            self.sb.SetStatusText(os.getcwd())
            self.Center()
            self.Show(True)
     
     
        def OnExit(self,e):
            self.Close(True)
     
        def OnSize(self, event):
            size = self.GetSize()
            self.splitter.SetSashPosition(size.x / 2)
            self.sb.SetStatusText(os.getcwd())
            event.Skip()
     
     
        def OnDoubleClick(self, event):
            size =  self.GetSize()
            self.splitter.SetSashPosition(size.x / 2)
     
    app = wx.App(0)
    FileHunter(None, -1, 'File Hunter')
    app.MainLoop()

    电子表格

    Gnumeric, KSpread, 和 OpenOffice Calc 都是 Unix 上著名的电子表格。下面的例子展示了一个 wxPython 电子表格的例子。

    应用有他们自己的生命,教程样例也一样。在升级到 wxPython 2.8.11 之后,我意识到电子表格的样例无法工作了,下面这一行是问题所在:

    1
    toolbar2.AddControl(wx.StaticText(toolbar2, -1, '  '))

    当然,我们没办法给部件自己添加自己。但是之前的版本却可以接受这样的设置。目前的版本下,这无法工作并报错,可能无法在 Mac 或 Windows 上允许。我本来的目的是想在 combo box 之间多加一些空间,现在没法运行了所以我去掉了线。

    除了修复这一 bug 之外,我也对代码进行了整理,使用新的 AddLabelTool() 代替了旧的 AddSimpleTool()。

    tutorial wxpython-jiaocheng

    #!/usr/bin/python
     
    # spreadsheet.py
     
    from wx.lib import sheet
    import wx
     
     
    class MySheet(sheet.CSheet):
        def __init__(self, parent):
            sheet.CSheet.__init__(self, parent)
            self.row = self.col = 0
            self.SetNumberRows(55)
            self.SetNumberCols(25)
     
            for i in range(55):
                self.SetRowSize(i, 20)
     
        def OnGridSelectCell(self, event):
            self.row, self.col = event.GetRow(), event.GetCol()
            control = self.GetParent().GetParent().position
            value =  self.GetColLabelValue(self.col) + self.GetRowLabelValue(self.row)
            control.SetValue(value)
            event.Skip()
     
    class Newt(wx.Frame):
        def __init__(self, parent, id, title):
            wx.Frame.__init__(self, parent, -1, title, size = (550, 500))
     
            fonts = ['Times New Roman', 'Times', 'Courier', 'Courier New', 'Helvetica',
                    'Sans', 'verdana', 'utkal', 'aakar', 'Arial']
            font_sizes = ['10', '11', '12', '14', '16']
     
            box = wx.BoxSizer(wx.VERTICAL)
            menuBar = wx.MenuBar()
     
            menu1 = wx.Menu()
            menuBar.Append(menu1, '&File')
            menu2 = wx.Menu()
            menuBar.Append(menu2, '&Edit')
            menu3 = wx.Menu()
            menuBar.Append(menu3, '&Edit')
            menu4 = wx.Menu()
            menuBar.Append(menu4, '&Insert')
            menu5 = wx.Menu()
            menuBar.Append(menu5, 'F&ormat')
            menu6 = wx.Menu()
            menuBar.Append(menu6, '&Tools')
            menu7 = wx.Menu()
            menuBar.Append(menu7, '&Data')
            menu8 = wx.Menu()
            menuBar.Append(menu8, '&Help')
     
            self.SetMenuBar(menuBar)
     
            toolbar1 = wx.ToolBar(self, -1, style= wx.TB_HORIZONTAL)
            toolbar1.AddLabelTool(-1, '', wx.Bitmap('icons/stock_new.png'))
            toolbar1.AddLabelTool(-1, '', wx.Bitmap('icons/stock_open.png'))
            toolbar1.AddLabelTool(-1, '', wx.Bitmap('icons/stock_save.png'))
            toolbar1.AddSeparator()
            toolbar1.AddLabelTool(-1, '', wx.Bitmap('icons/stock_cut.png'))
            toolbar1.AddLabelTool(-1, '', wx.Bitmap('icons/stock_copy.png'))
            toolbar1.AddLabelTool(-1, '', wx.Bitmap('icons/stock_paste.png'))
            toolbar1.AddLabelTool(-1, '',  wx.Bitmap('icons/stock_delete.png'))
            toolbar1.AddSeparator()
            toolbar1.AddLabelTool(-1, '', wx.Bitmap('icons/stock_undo.png'))
            toolbar1.AddLabelTool(-1, '', wx.Bitmap('icons/stock_redo.png'))
            toolbar1.AddSeparator()
            toolbar1.AddLabelTool(-1, '', wx.Bitmap('icons/incr22.png'))
            toolbar1.AddLabelTool(-1, '', wx.Bitmap('icons/decr22.png'))
            toolbar1.AddSeparator()
            toolbar1.AddLabelTool(-1, '', wx.Bitmap('icons/chart.xpm'))
            toolbar1.AddSeparator()
            toolbar1.AddLabelTool(-1, '',  wx.Bitmap('icons/stock_exit.png'))
     
            toolbar1.Realize()
     
            toolbar2 = wx.ToolBar(self, wx.TB_HORIZONTAL | wx.TB_TEXT)
     
            self.position = wx.TextCtrl(toolbar2)
            font = wx.ComboBox(toolbar2, -1, value = 'Times', choices=fonts, size=(100, -1),
                    style=wx.CB_DROPDOWN)
            font_height = wx.ComboBox(toolbar2, -1, value = '10',  choices=font_sizes,
                    size=(50, -1), style=wx.CB_DROPDOWN)
     
            toolbar2.AddControl(self.position)
            toolbar2.AddControl(font)
            toolbar2.AddControl(font_height)
            toolbar2.AddSeparator()
            bold = wx.Bitmap('icons/stock_text_bold.png')
            toolbar2.AddCheckTool(-1, bold)
            italic = wx.Bitmap('icons/stock_text_italic.png')
            toolbar2.AddCheckTool(-1, italic)
            under = wx.Bitmap('icons/stock_text_underline.png')
            toolbar2.AddCheckTool(-1, under)
            toolbar2.AddSeparator()
            toolbar2.AddLabelTool(-1, '', wx.Bitmap('icons/text_align_left.png'))
            toolbar2.AddLabelTool(-1, '', wx.Bitmap('icons/text_align_center.png'))
            toolbar2.AddLabelTool(-1, '', wx.Bitmap('icons/text_align_right.png'))
     
            box.Add(toolbar1, border=5)
            box.Add((5,5) , 0)
            box.Add(toolbar2)
            box.Add((5,10) , 0)
     
            toolbar2.Realize()
            self.SetSizer(box)
            notebook = wx.Notebook(self, -1, style=wx.RIGHT)
     
            sheet1 = MySheet(notebook)
            sheet2 = MySheet(notebook)
            sheet3 = MySheet(notebook)
            sheet1.SetFocus()
     
            notebook.AddPage(sheet1, 'Sheet1')
            notebook.AddPage(sheet2, 'Sheet2')
            notebook.AddPage(sheet3, 'Sheet3')
     
            box.Add(notebook, 1, wx.EXPAND)
     
            self.CreateStatusBar()
            self.Centre()
            self.Show(True)
     
    app = wx.App()
    Newt(None, -1, 'SpreadSheet')
    app.MainLoop()
    

    大多数代码在构建菜单和工具栏,这是一个相当简单的例子。

    class MySheet(sheet.CSheet):
        def __init__(self, parent):
            sheet.CSheet.__init__(self, parent)
            self.row = self.col = 0
            self.SetNumberRows(55)
            self.SetNumberCols(25)
     
            for i in range(55):
                self.SetRowSize(i, 20)

    MySheet 类继承自 CSheet 类,它位于 wx.lib 模块,它是一个拥有一些附加功能的 wx.Grid 部件。我们把行大小设置为 20px,这仅仅是为了更美观。

    control = self.GetParent().GetParent().position

    位置文本部件显示了 grid 部件中被选择的单元格的位置,它位于第二个工具栏的第一个。在 MySheet 类中,我们需要引用位置文本部件,它被定义在 Newt 类中。MySheet 是 notebook 的子代,notebook 是 Newt 的子代,所以我们可以调用两次 GetParent() 方法来获取位置文本部件。

    notebook = wx.Notebook(self, -1, style=wx.RIGHT)

    上面是一行涉及一个目前版本的 bug(GTK+),右侧和底部弄反了。

    播放器

    下面的例子是一个典型的视频播放器的骨架。

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
     
    import wx
     
     
    class Example(wx.Frame):
                
        def __init__(self, *args, **kw):
            super(Example, self).__init__(*args, **kw) 
             
            self.InitUI()
             
        def InitUI(self):   
     
            self.CreateMenuBar()
         
            panel = wx.Panel(self)
     
            pnl1 = wx.Panel(self)
            pnl1.SetBackgroundColour(wx.BLACK)
            pnl2 = wx.Panel(self)        
     
            slider1 = wx.Slider(pnl2, value=18, minValue=0, maxValue=1000)
            pause = wx.BitmapButton(pnl2, bitmap=wx.Bitmap('pause.png'))
            play  = wx.BitmapButton(pnl2, bitmap=wx.Bitmap('play.png'))
            forw  = wx.BitmapButton(pnl2, bitmap=wx.Bitmap('forw.png'))
            back  = wx.BitmapButton(pnl2, bitmap=wx.Bitmap('back.png'))
            vol = wx.BitmapButton(pnl2, bitmap=wx.Bitmap('volume.png'))
            slider2 = wx.Slider(pnl2, value=1, minValue=0, maxValue=100, 
                size=(120, -1))
     
            vbox = wx.BoxSizer(wx.VERTICAL)
            hbox1 = wx.BoxSizer(wx.HORIZONTAL)
            hbox2 = wx.BoxSizer(wx.HORIZONTAL)
     
            hbox1.Add(slider1, proportion=1)
            hbox2.Add(pause)
            hbox2.Add(play, flag=wx.RIGHT, border=5)
            hbox2.Add(forw, flag=wx.LEFT, border=5)
            hbox2.Add(back)
            hbox2.Add((-1, -1), proportion=1)
            hbox2.Add(vol)
            hbox2.Add(slider2, flag=wx.TOP|wx.LEFT, border=5)
     
            vbox.Add(hbox1, flag=wx.EXPAND|wx.BOTTOM, border=10)
            vbox.Add(hbox2, proportion=1, flag=wx.EXPAND)
            pnl2.SetSizer(vbox)
     
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(pnl1, proportion=1, flag=wx.EXPAND)
            sizer.Add(pnl2, flag=wx.EXPAND|wx.BOTTOM|wx.TOP, border=10)
     
            self.SetMinSize((350, 300))
            self.CreateStatusBar()
            self.SetSizer(sizer)
     
            self.SetSize((350, 200))
            self.SetTitle('Player')
            self.Centre()
            self.Show(True)          
             
        def CreateMenuBar(self):
             
            menubar = wx.MenuBar()
            filem = wx.Menu()
            play = wx.Menu()
            view = wx.Menu()
            tools = wx.Menu()
            favorites = wx.Menu()
            help = wx.Menu()
             
            filem.Append(wx.ID_ANY, '&quit', 'Quit application')
     
            menubar.Append(filem, '&File')
            menubar.Append(play, '&Play')
            menubar.Append(view, '&View')
            menubar.Append(tools, '&Tools')
            menubar.Append(favorites, 'F&avorites')
            menubar.Append(help, '&Help')
     
            self.SetMenuBar(menubar)        
                           
    def main():
         
        ex = wx.App()
        Example(None)
        ex.MainLoop()    
     
    if __name__ == '__main__':
        main()          

    为了构建界面,我们使用了 bitmap 按钮、滑块、面板和菜单栏。

    pnl1 = wx.Panel(self)
    pnl1.SetBackgroundColour(wx.BLACK)

    应用的主要区域使用一个黑色背景的 panel。

    slider1 = wx.Slider(pnl2, value=18, minValue=0, maxValue=1000)

    滑块 wx.Slider 是为了展示影片当前的进度。

    pause = wx.BitmapButton(pnl2, bitmap=wx.Bitmap('pause.png'))
    play  = wx.BitmapButton(pnl2, bitmap=wx.Bitmap('play.png'))

    Bitmap 按钮是为了控制影片播放。

    self.SetMinSize((350, 300))

    这里,我们设置了播放器为最小尺寸,将窗口大小调整到比它还小就没有什么意义了。

    tutorial wxpython-jiaocheng

    浏览器

    如今 IT 世界中最重要的应用就是网络浏览器,我们在脚本中模仿了 Firefox 的界面。

    tutorial wxpython-jiaocheng

    #!/usr/bin/python
     
    import wx
    from wx.lib.buttons import GenBitmapTextButton
     
    class Browser(wx.Frame):
        def __init__(self, parent, id, title):
            wx.Frame.__init__(self, parent, id, title, size=(450, 400))
            panel = wx.Panel(self, -1)
            panel.SetBackgroundColour('WHITE')
     
            menubar = wx.MenuBar()
            file = wx.Menu()
            file.Append(1, '&Quit', '')
            edit = wx.Menu()
            view = wx.Menu()
            go = wx.Menu()
            bookmarks = wx.Menu()
            tools = wx.Menu()
            help = wx.Menu()
     
            menubar.Append(file, '&File')
            menubar.Append(edit, '&Edit')
            menubar.Append(view, '&View')
            menubar.Append(go, '&Go')
            menubar.Append(bookmarks, '&Bookmarks')
            menubar.Append(tools, '&Tools')
            menubar.Append(help, '&Help')
     
            self.SetMenuBar(menubar)
     
            vbox = wx.BoxSizer(wx.VERTICAL)
            hbox1 = wx.BoxSizer(wx.HORIZONTAL)
            hbox2 = wx.BoxSizer(wx.HORIZONTAL)
            toolbar1 = wx.Panel(panel, -1, size=(-1, 40))
            back = wx.BitmapButton(toolbar1, -1, wx.Bitmap('icons/back.png'), 
                    style=wx.NO_BORDER)
            forward = wx.BitmapButton(toolbar1, -1, wx.Bitmap('icons/forward.png'), 
                    style=wx.NO_BORDER)
            refresh = wx.BitmapButton(toolbar1, -1, wx.Bitmap('icons/refresh.png'), 
                    style=wx.NO_BORDER)
            stop = wx.BitmapButton(toolbar1, -1, wx.Bitmap('icons/stop.png'), 
                    style=wx.NO_BORDER)
            home = wx.BitmapButton(toolbar1, -1, wx.Bitmap('icons/home.png'), 
                    style=wx.NO_BORDER)
            address = wx.ComboBox(toolbar1, -1, size=(50, -1))
            go = wx.BitmapButton(toolbar1, -1, wx.Bitmap('icons/go.png'), 
                    style=wx.NO_BORDER)
            text = wx.TextCtrl(toolbar1, -1, size=(150, -1))
     
            hbox1.Add(back)
            hbox1.Add(forward)
            hbox1.Add(refresh)
            hbox1.Add(stop)
            hbox1.Add(home)
            hbox1.Add(address, 1, wx.TOP, 4)
            hbox1.Add(go, 0, wx.TOP | wx.LEFT, 4)
            hbox1.Add(text, 0, wx.TOP | wx.RIGHT, 4)
     
            vbox.Add(toolbar1, 0, wx.EXPAND)
            line = wx.StaticLine(panel)
            vbox.Add(line, 0, wx.EXPAND)
     
            toolbar2 = wx.Panel(panel, -1, size=(-1, 30))
            bookmark1 = wx.BitmapButton(toolbar2, -1, wx.Bitmap('icons/love.png'), 
                    style=wx.NO_BORDER)
            bookmark2 = wx.BitmapButton(toolbar2, -1, wx.Bitmap('icons/books.png'), 
                    style=wx.NO_BORDER)
            bookmark3 = wx.BitmapButton(toolbar2, -1, wx.Bitmap('icons/sound.png'), 
                    style=wx.NO_BORDER)
            hbox2.Add(bookmark1, flag=wx.RIGHT, border=5)
            hbox2.Add(bookmark2, flag=wx.RIGHT, border=5)
            hbox2.Add(bookmark3)
            toolbar2.SetSizer(hbox2)
            vbox.Add(toolbar2, 0, wx.EXPAND)
            line = wx.StaticLine(panel)
            vbox.Add(line, 0, wx.EXPAND)
     
            panel.SetSizer(vbox)
     
            self.CreateStatusBar()
            self.Centre()
            self.Show(True)
     
    app = wx.App(0)
    Browser(None, -1, 'Browser')
    app.MainLoop()

    问题在于,如何创建一个在 Firefox 和 Opera 中都会使用的 combo box (地址栏下拉框) 呢?无法使用 wx.Toolbar 来创建,所以必须做一个变通的方法。

    toolbar1 = wx.Panel(panel, -1, size=(-1, 40))

    技巧很简单,我们创建了一个 plain 的 wx.Panel。

    hbox1 = wx.BoxSizer(wx.HORIZONTAL)
    ...
    hbox1.Add(back)
    hbox1.Add(forward)
    hbox1.Add(refresh)
    

    我们创建了一个水平的 sizer 并添加了需要的按钮。 

    hbox1.Add(address, 1, wx.TOP, 4)

    然后我们把 combo box 添加到 sizer 中,这种 combo box 被称作地址栏。主要到这个部件是唯一的需要将 proportion 设置为 1 的部件。有必要将其设置为可改变大小的。

    采用类似的方式创建第二个菜单栏,使用一条线来分割菜单栏。刚开始我以为应该可以用 panel 的边框来实现,后来经过测试发现不满意。

    line = wx.StaticLine(panel)

    然后我突然发现了这个,如此简单!

    有时,没有合适部件的时候,我们必须创建新的解决办法。但根据直觉,往往我们能很容易找到办法。

    本节,我们创建了一些应用骨架。

  • 相关阅读:
    学习另外一门技术,叫Python
    子报表显示Total Page Count或Page Number
    Insus.NET是Leo Yeung的网名
    C# 以管理员身份运行WinForm程序
    python 里 certifi 库的作用
    CEF中文教程(google chrome浏览器控件) -- CEF简介CEF中文教程(google chrome浏览器控件) -- CEF简介
    CefInitialize崩溃 && Cef白屏
    Chrome设置
    CEF 开启webGl功能
    Qt5.9.1结合CEF开发基于chorm的浏览器(二)
  • 原文地址:https://www.cnblogs.com/-wenli/p/12350584.html
Copyright © 2020-2023  润新知