pygame中的浏览器组件

pygame中的浏览器组件,第1张

原理

使用Windows API创建IE窗口,并将其嵌入到pygame窗口中,利用user32.dll调整位置

代码
"""
本段代码在pycharm中将有语法报错,但运行正常。
"""

import ctypes
import sys
from typing import Tuple, Callable, Any

import pygame

if sys.platform != 'win32':
    raise OSError('Only supported Windows OS')

import threading
import clr

try:
    clr.AddReference('System.Windows.Forms')
    clr.AddReference('System.Threading')
except OSError:
    raise OSError('Only supported Windows OS') from None
from System.Windows.Forms import *  # pycharm报语法错误
from System.Threading import Thread, ApartmentState, ThreadStart  # pycharm报语法错误

_app = Application  # pycharm报语法错误
_user32 = ctypes.windll.user32


class _Form(object):
    pass


class WebView(object):
    def __init__(self, window: pygame.Surface, size: Tuple[int, int] = (1200, 550), url: str = '',
                 script_errors_suppressed: bool = True, menu_enabled: bool = False):
        
        self._width, self._height = size
        
        form = _Form()
        threading.Thread(target=self._get_web, args=(form, self._width, self._height)).start()
        
        while True:
            try:
                ie = form.web
                break
            except AttributeError:
                pass
        
        ie.ScriptErrorsSuppressed = script_errors_suppressed
        self.ie_hwnd = int(str(ie.Handle))
        self.x, self.y = 0, 0
        _user32.SetParent(self.ie_hwnd, pygame.display.get_wm_info()['window'])  # 嵌入窗口
        _user32.MoveWindow(self.ie_hwnd, self.x, self.y, self._width, self._height, True)  # 移动窗口
        
        if url != '':
            ie.Navigate(url)
        self.ie = ie
        self.ie.IsWebBrowserContextMenuEnabled = menu_enabled
        self.ie.NewWindow += self._before_window
    
    @staticmethod
    def _get_web(form: _Form, width: int, height: int):
        web = WebBrowser()  # pycharm报语法错误
        form.web = web
        web.Width = width
        web.Height = height
    
    @staticmethod
    def _before_window(sender, e):
        href = sender.Document.ActiveElement.GetAttribute('href')
        sender.Navigate(href)
        e.Cancel = True
    
    @property
    def pos(self):
        return self.x, self.y
    
    @pos.setter
    def pos(self, set_pos: Tuple[int, int]):
        self.x, self.y = set_pos
        _user32.MoveWindow(self.ie_hwnd, self.x, self.y, self._width, self._height, True)
    
    def set_url(self, url: str):
        self.ie.Navigate(url)
    
    def show_url(self, func: Callable[[], Any]):
        self.ie.Navigating += func
    
    def resize(self, width: int, height: int):
        self._width, self._height = width, height
        self.ie.Width = width
        self.ie.Height = height
    
    def destroy(self):
        self.ie.Dispose()
        del self.ie
        
        
def test():
    pygame.init()
    screen = pygame.display.set_mode((500, 500))
    pygame.display.set_caption('演示')
    web_view = WebView(screen, size=(500, 500), url='baidu.com')
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit(0)
        pygame.display.update()
 
        
test()
效果

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/870742.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存