wxpython + cef 是优秀的 WebView 组件

news2024/11/15 23:54:27

CEF 即 (Chromium Embedded Framework);cef 是优秀的 WebView 组件。

pip install wxpython==4.2
wxPython-4.2.0-cp37-cp37m-win_amd64.whl (18.0 MB)
Successfully installed wxpython-4.2.0

pip install cefpython3
cefpython3-66.1-py2.py3-none-win_amd64.whl (69.0 MB)
Successfully installed cefpython3-66.1

cd \Python37\Lib\site-packages\cefpython3\examples
copy wxpython.py  wx_cef.py
用的图片在 \Python37\Lib\site-packages\cefpython3\examples\resources\
编写 wx_cef.py  如下

# -*- coding: utf-8 -*-
# Example of embedding CEF Python browser using wxPython library.
# This example has a top menu and a browser widget without navigation bar.

# Tested configurations:
# - wxPython 4.0 on Windows/Mac/Linux
# - wxPython 3.0 on Windows/Mac
# - wxPython 2.8 on Linux
# - CEF Python v66.0+

import os
import sys
import platform
import wx
from cefpython3 import cefpython as cef

# Platforms
WINDOWS = (platform.system() == "Windows")
LINUX = (platform.system() == "Linux")
MAC = (platform.system() == "Darwin")

if MAC:
    try:
        # noinspection PyUnresolvedReferences
        from AppKit import NSApp
    except ImportError:
        print("[wx_cef.py] Error: PyObjC package is missing, "
              "cannot fix Issue #371")
        print("[wx_cef.py] To install PyObjC type: "
              "pip install -U pyobjc")
        sys.exit(1)

# Configuration
WIDTH =  900
HEIGHT = 600

# Globals
g_count_windows = 0
baseurl = "http://localhost:8888/"

def main():
    check_versions()
    sys.excepthook = cef.ExceptHook  # To shutdown all CEF processes on error
    settings = {}
    if MAC:
        # Issue #442 requires enabling message pump on Mac
        # and calling message loop work in a timer both at
        # the same time. This is an incorrect approach
        # and only a temporary fix.
        settings["external_message_pump"] = True
    if WINDOWS: pass
        # noinspection PyUnresolvedReferences, PyArgumentList
        #cef.DpiAware.EnableHighDpiSupport()
    cef.Initialize(settings=settings)
    app = CefApp(False)
    app.MainLoop()
    del app  # Must destroy before calling Shutdown
    if not MAC:
        # On Mac shutdown is called in OnClose
        cef.Shutdown()


def check_versions():
    print("[wx_cef.py] CEF Python {ver}".format(ver=cef.__version__))
    print("[wx_cef.py] Python {ver} {arch}".format(
            ver=platform.python_version(), arch=platform.architecture()[0]))
    print("[wx_cef.py] wxPython {ver}".format(ver=wx.version()))
    # CEF Python version requirement
    assert cef.__version__ >= "66.0", "CEF Python v66.0+ required to run this"


def scale_window_size_for_high_dpi(width, height):
    """Scale window size for high DPI devices. This func can be
    called on all operating systems, but scales only for Windows.
    If scaled value is bigger than the work area on the display
    then it will be reduced."""
    if not WINDOWS:
        return width, height
    (_, _, max_width, max_height) = wx.GetClientDisplayRect().Get()
    # noinspection PyUnresolvedReferences
    (width, height) = cef.DpiAware.Scale((width, height))
    if width > max_width:
        width = max_width
    if height > max_height:
        height = max_height
    return width, height


class MainFrame(wx.Frame):

    def __init__(self):
        self.browser = None

        # Must ignore X11 errors like 'BadWindow' and others by
        # installing X11 error handlers. This must be done after
        # wx was intialized.
        if LINUX:
            cef.WindowUtils.InstallX11ErrorHandlers()

        global g_count_windows
        g_count_windows += 1

        if WINDOWS:
            # noinspection PyUnresolvedReferences, PyArgumentList
            print("[wx_cef.py] System DPI settings: %s"
                  % str(cef.DpiAware.GetSystemDpi()))
        if hasattr(wx, "GetDisplayPPI"):
            print("[wx_cef.py] wx.GetDisplayPPI = %s" % wx.GetDisplayPPI())
        print("[wx_cef.py] wx.GetDisplaySize = %s" % wx.GetDisplaySize())

        print("[wx_cef.py] MainFrame declared size: %s"
              % str((WIDTH, HEIGHT)))
        size = scale_window_size_for_high_dpi(WIDTH, HEIGHT)
        print("[wx_cef.py] MainFrame DPI scaled size: %s" % str(size))

        wx.Frame.__init__(self, parent=None, id=wx.ID_ANY,
                          title='wxPython + cef', size=size)
        # wxPython will set a smaller size when it is bigger
        # than desktop size.
        print("[wx_cef.py] MainFrame actual size: %s" % self.GetSize())

        self.setup_icon()
        self.create_menu()
        self.Bind(wx.EVT_CLOSE, self.OnClose)

        # Set wx.WANTS_CHARS style for the keyboard to work.
        # This style also needs to be set for all parent controls.
        self.browser_panel = wx.Panel(self, style=wx.WANTS_CHARS)
        self.browser_panel.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
        self.browser_panel.Bind(wx.EVT_SIZE, self.OnSize)

        if MAC:
            # Make the content view for the window have a layer.
            # This will make all sub-views have layers. This is
            # necessary to ensure correct layer ordering of all
            # child views and their layers. This fixes Window
            # glitchiness during initial loading on Mac (Issue #371).
            NSApp.windows()[0].contentView().setWantsLayer_(True)

        if LINUX:
            # On Linux must show before embedding browser, so that handle
            # is available (Issue #347).
            self.Show()
            # In wxPython 3.0 and wxPython 4.0 on Linux handle is
            # still not yet available, so must delay embedding browser
            # (Issue #349).
            if wx.version().startswith("3.") or wx.version().startswith("4."):
                wx.CallLater(100, self.embed_browser)
            else:
                # This works fine in wxPython 2.8 on Linux
                self.embed_browser()
        else:
            self.embed_browser()
            self.Show()

    def setup_icon(self):
        icon_file = os.path.join(os.path.abspath(os.path.dirname(__file__)),
                                 "resources", "wxpython.png")
        # wx.IconFromBitmap is not available on Linux in wxPython 3.0/4.0
        if os.path.exists(icon_file) and hasattr(wx, "IconFromBitmap"):
            icon = wx.IconFromBitmap(wx.Bitmap(icon_file, wx.BITMAP_TYPE_PNG))
            self.SetIcon(icon)

    def create_menu(self):
        filemenu = wx.Menu()
        filemenu.Append(1, "Open Url")
        filemenu.Append(2, "Open File")
        menubar = wx.MenuBar()
        menubar.Append(filemenu, "&File")
        self.SetMenuBar(menubar)
        self.Bind(wx.EVT_MENU_OPEN, self.OnOpenUrl)

    def embed_browser(self):
        window_info = cef.WindowInfo()
        (width, height) = self.browser_panel.GetClientSize().Get()
        assert self.browser_panel.GetHandle(), "Window handle not available"
        window_info.SetAsChild(self.browser_panel.GetHandle(),[0,0,width,height])
        self.browser = cef.CreateBrowserSync(window_info, url=baseurl)
        self.browser.SetClientHandler(FocusHandler())

    def OnOpenUrl(self, event):
        dlg = wx.TextEntryDialog(self, "Open Location",
                                "Enter a full URL or local path",
                                "http://", wx.OK|wx.CANCEL)
        dlg.CentreOnParent()
        global baseurl
        if dlg.ShowModal() == wx.ID_OK:
            baseurl = dlg.GetValue()
            self.browser.LoadUrl(baseurl)
        dlg.Destroy()

    def OnSetFocus(self, _):
        if not self.browser:
            return
        if WINDOWS:
            cef.WindowUtils.OnSetFocus(self.browser_panel.GetHandle(), 0,0,0)
        self.browser.SetFocus(True)

    def OnSize(self, _):
        if not self.browser:
            return
        if WINDOWS:
            cef.WindowUtils.OnSize(self.browser_panel.GetHandle(), 0,0,0)
        elif LINUX:
            (x, y) = (0, 0)
            (width, height) = self.browser_panel.GetSize().Get()
            self.browser.SetBounds(x, y, width, height)
        self.browser.NotifyMoveOrResizeStarted()

    def OnClose(self, event):
        print("[wx_cef.py] OnClose called")
        if not self.browser:
            # May already be closing, may be called multiple times on Mac
            return

        if MAC:
            # On Mac things work differently, other steps are required
            self.browser.CloseBrowser()
            self.clear_browser_references()
            self.Destroy()
            global g_count_windows
            g_count_windows -= 1
            if g_count_windows == 0:
                cef.Shutdown()
                wx.GetApp().ExitMainLoop()
                # Call _exit otherwise app exits with code 255 (Issue #162).
                # noinspection PyProtectedMember
                os._exit(0)
        else:
            # Calling browser.CloseBrowser() and/or self.Destroy()
            # in OnClose may cause app crash on some paltforms in
            # some use cases, details in Issue #107.
            self.browser.ParentWindowWillClose()
            event.Skip()
            self.clear_browser_references()

    def clear_browser_references(self):
        # Clear browser references that you keep anywhere in your
        # code. All references must be cleared for CEF to shutdown cleanly.
        self.browser = None


class FocusHandler(object):
    def OnGotFocus(self, browser, **_):
        # Temporary fix for focus issues on Linux (Issue #284).
        if LINUX:
            print("[wx_cef.py] FocusHandler.OnGotFocus:"
                  " keyboard focus fix (Issue #284)")
            browser.SetFocus(True)


class CefApp(wx.App):

    def __init__(self, redirect):
        self.timer = None
        self.timer_id = 1
        self.is_initialized = False
        super(CefApp, self).__init__(redirect=redirect)

    def OnPreInit(self):
        super(CefApp, self).OnPreInit()
        # On Mac with wxPython 4.0 the OnInit() event never gets
        # called. Doing wx window creation in OnPreInit() seems to
        # resolve the problem (Issue #350).
        if MAC and wx.version().startswith("4."):
            print("[wx_cef.py] OnPreInit: initialize here"
                  " (wxPython 4.0 fix)")
            self.initialize()

    def OnInit(self):
        self.initialize()
        return True

    def initialize(self):
        if self.is_initialized:
            return
        self.is_initialized = True
        self.create_timer()
        frame = MainFrame()
        self.SetTopWindow(frame)
        frame.Show(True)

    def create_timer(self):
        # See also "Making a render loop":
        # http://wiki.wxwidgets.org/Making_a_render_loop
        # Another way would be to use EVT_IDLE in MainFrame.
        self.timer = wx.Timer(self, self.timer_id)
        self.Bind(wx.EVT_TIMER, self.on_timer, self.timer)
        self.timer.Start(10)  # 10ms timer

    def on_timer(self, _):
        cef.MessageLoopWork()

    def OnExit(self):
        self.timer.Stop()
        return 0


if __name__ == '__main__':
    main()

运行 python wx_cef.py

我注释了 #cef.DpiAware.EnableHighDpiSupport() ,以避免cef 刷新不完善时造成显示重影。

web 服务程序参见: python:mdict + bottle = web 查询英汉词典

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/934272.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot+vue基于 JAVA 的医院门诊信息管理系统的设计与实现 f1ls0

系统根据现有的管理模块进行开发和扩展,采用面向对象的开发的思想和结构化的开发方法对医院门诊信息的现状进行系统调查。采用结构化的分析设计,该方法要求结合一定的图表,在模块化的基础上进行系统的开发工作。在设计中采用“自下而上”的思…

多线程和并发(1)—等待/通知模型

一、进程通信和进程同步 1.进程通信的方法 同一台计算机的进程通信称为IPC(Inter-process communication),不同计 算机之间的进程通信被称为 RPC(Romote process communication),需要通过网络,并遵守共同的协议。**进…

每日三题 1448统计二叉树中好节点的个数 100相同的树 101对称二叉树

1448 题目 给你一棵根为 root 的二叉树,请你返回二叉树中好节点的数目。 「好节点」X 定义为:从根到该节点 X 所经过的节点中,没有任何节点的值大于 X 的值。 示例 1: 输入:root [3,1,4,3,null,1,5] 输出&#xff…

2021-05-25 rs485保护电路

今天给大家分享485接口的EMC设计,希望对电路设计,及相关软件开发的人员有帮助。 一、原理图 1. RS485接口6KV防雷电路设计方案 (RS485接口防雷电路) 接口电路设计概述: RS485用于设备与计算机或其它设备之间通讯&…

攻防世界-Web_php_unserialize

原题 解题思路 注释说了flag存在f14g.php中,但是在wakeup函数中,会把传入的文件名变成index.php。看wp知道,如果被反序列话的字符串其中对应的对象的属性个数发生变化时,会导致反序列化失败而同时使得__wakeup 失效(CV…

Qt/C++编写视频监控系统80-远程回放视频流

一、前言 远程回放NVR或者服务器上的视频文件,一般有三种方式,第一种是调用厂家的SDK,这个功能最全,但是缺点明显就是每个厂家的设备都有自己的SDK,只兼容自家的设备,如果你的软件需要接入多个厂家的&…

STM32新手入门-什么是寄存器

✅作者简介:嵌入式入坑者,与大家一起加油,希望文章能够帮助各位!!!! 📃个人主页:rivencode的个人主页 🔥系列专栏:玩转STM32 💬保持学…

小程序外包开发上线的问题解决

在小程序上线过程中,可能会遇到各种问题。解决问题的关键是保持沟通、持续改进和测试。小程序的上线后维护同样重要,要不断关注用户反馈和市场变化,及时做出调整和优化。以下是一些常见问题及其可能的解决方案,希望对大家有所帮助…

FL水果21.1全新版本下载FL Studio新增功能讲解

FL Studio就是国人众所熟知的水果编曲软件,圈内用户习惯叫它“水果”。它是一个全能音乐制作环境和数字音频工作站(DAW)。FL Studio可以进行编曲、剪辑、录音、混音,让你的电脑变成全功能录音室,帮助你制作出属于自己的…

各地区结婚、离婚、再婚等数据(1990-2021年)

涵盖了1990年至2021年各地区的结婚、离婚以及再婚情况。通过对此数据进行分析,我们可以了解婚姻趋势的演变和地区之间的差异。数据反映了人们的婚姻决策、家庭变化以及社会动态,为研究家庭结构和社会变迁提供了有价值的信息。 一、数据介绍 数据名称&a…

基于树莓派的智能小车 python

摘要 playWithRaspberryPi 实战笔记 raspberrypi_cookbook 树莓派python代码本 树莓派(Raspberry Pi)是一种小型的单片机计算机; 它可以通过其引脚和接口与外部硬件通信。 Pi(树莓派的简称)展示了我们可以如何分解大型的Realbox机器, 使Dynamicland成…

如何在windows下使用masm和link对汇编文件进行编译

前言 32位系统带有debug程序,可以进行汇编语言和exe的调试。但真正的汇编编程是“编辑汇编程序文件(.asm)->编译生成obj文件->链接生成exe文件”。下面,我就来说一下如何在windows下使用masm调试,使用link链接。 1、下载相应软件 下载…

Linux系统编程系列之进程间通信(IPC)-管道

一、什么是管道 在Linux系统下,一切皆文件,所以管道就是一个文件,用来实现进程间通信的一种方式。分析小技巧:对于一些陌生的概念,都把它当成是文件,然后操作的时候,就是三部曲。文件打开&#…

香港服务器是什么?

香港服务器是指位于香港地区的云服务器或物理服务器。香港作为一个重要的国际金融和商业中心,具有良好的地理位置和先进的网络基础设施。香港服务器提供稳定的网络连接和高性能,可用于托管网站、应用程序和数据存储等各种互联网服务。 香港服务器具有以…

精准测试——持续测试

前面已经介绍了黑盒测试和白盒测试。从前面的介绍中可以知道,黑盒测试是一种面向业务流程的测试,针对需求设计测试用例,在运行的系统上执行测试用例,完成测试。 整个测试过程中测试工程师对于测试代码是如何运行的一无所知&#…

深度学习算法模型转成算能科技平台xx.bmodel模型的方法步骤

目录 1 docker镜像下载 2 SDK下载 3 下载sophon-demo 4 修改docker镜像的脚本 5 创建个文件夹 6.source 7.转模型 1 docker镜像下载 可以在dockerhub看到镜像的相关信息 https://hub.docker.com/r/sophgo/tpuc_dev/tags 用下面的命令下载 docker pull sophgo/tpuc_d…

vim练习题

在普通模式 / 可以用来寻找 . 是重复上次的动作,$ 是移动到末尾 直接查找 .vimrc 保存后重启 安装curl 出现问题 宏 通过记录在寄存器中,让寄存器知道怎么操作 宏只能在1 2 4 寄存器上面使用 替代命令,将匹配到的,包括这些内容…

【力扣每日一题】2023.8.27 合并区间

目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 那么合并区间是在什么情况下才能合并呢? 我总结为两种情况 第一种情况就是这样,第二个区间的左区间大于第一个区…

算法通关村第十四关——堆

堆是将一组数据按照完全二叉树的存储顺序,将数据存储在一个一维数组中的结构。堆有两种结构,一种称为大顶堆,一种称为小顶堆,如下图。 小顶堆:任意节点的值均小于等于它的左右孩子,并且最小的值位于堆顶&am…

哪个蓝牙耳机打电话比较好,打电话降噪蓝牙耳机推荐

近年来,骨传导耳机的市场表现出了显著的增长,其市场竞争也变得异常激烈,与传统无线耳机相比,“骨传导耳机”的知名度还达不到举世皆知的地步,但对于运动群体以及部分有听力损伤的群体来说,骨传导耳机还是有…