Пример #1
0
    def setupView(self, webView: WebView):
        webPage = webView.page()

        webView.titleChanged.connect(self._title_changed)
        webView.urlChanged.connect(self._url_changed)
        webView.loadProgress.connect(self._load_progress)
        webPage.linkHovered.connect(self._link_hovered)
        webPage.iconChanged.connect(self._icon_changed)
        webView.webActionEnabledChanged.connect(
            self._web_action_enabled_changed)
        webView.loadStarted.connect(self._load_started)
        webPage.windowCloseRequested.connect(self._window_close_requested)
Пример #2
0
class WebPopupWindow(QWidget):
    def __init__(self, profile: QWebEngineProfile):
        super().__init__()

        self.m_addressBar = UrlLineEdit(self)
        self.m_view = WebView(self)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)

        layout = QVBoxLayout()
        # layout.setMargin(0)
        self.setLayout(layout)
        layout.addWidget(self.m_addressBar)
        layout.addWidget(self.m_view)

        self.m_view.setPage(WebPage(profile, self.m_view))
        self.m_view.setFocus()
        self.m_addressBar.setReadOnly(True)
        self.m_addressBar.setFavIcon(QIcon(":defaulticon.png"))

        self.m_view.titleChanged.connect(self.setWindowTitle)
        self.m_view.urlChanged.connect(self.setUrl)
        self.m_view.page().iconChanged.connect(self.handleIconChanged)
        self.m_view.page().geometryChangeRequested.connect(
            self.handleGeometryChangeRequested)
        self.m_view.page().windowCloseRequested.connect(self.close)

    def view(self) -> QWebEngineView:
        return self.m_view

    def setUrl(self, url: QUrl):
        self.m_addressBar.setUrl(url)

    def handleGeometryChangeRequested(self, newGeometry: QRect):
        self.m_view.setMinimumSize(newGeometry.width(), newGeometry.height())
        self.move(newGeometry.topLeft() - self.m_view.pos())
        # let the layout do the magic
        self.resize(0, 0)
        self.show()

    def handleIconChanged(self, icon: QIcon):
        if icon.isNull():
            self.m_addressBar.setFavIcon(QIcon(":defaulticon.png"))
        else:
            self.m_addressBar.setFavIcon(icon)
Пример #3
0
class Browser(QObject):

    comment_postdata_example = {
            'ft_ent_identifier': '735272899920440', # ИД сообщения
            'comment_text': 'Cool))', # Текст коментария
            'source': '22',
            'client_id': '1429632677205%3A3425397009',
            'reply_fbid': '',
            'parent_comment_id': '',
            'rootid': 'u_ps_0_0_k',
            'clp': '',
            'attached_sticker_fbid': '0',
            'attached_photo_fbid': '0',
            'feed_context': '%7B%22fbfeed_context%22%3Atrue%2C%22location_type%22%3A36%2C%22is_starred%22%3Afalse%2C%22is_pinned_post%22%3Afalse%2C%22can_moderate_timeline_story%22%3Afalse%2C%22profile_id%22%3A308106089303792%2C%22outer_object_element_id%22%3A%22u_ps_0_0_0%22%2C%22object_element_id%22%3A%22u_ps_0_0_0%22%2C%22is_ad_preview%22%3Afalse%2C%22is_editable%22%3Afalse%7D',
            'ft[tn]': '[]',
            'ft[top_level_post_id]': '750869418360788',
            'ft[fbfeed_location]': '36',
            'nctr[_mod]': 'pagelet_timeline_main_column',
            'av': '100009110845526',
            '__user': '******',
            '__a': '1',
            '__dyn': '', #пустой
            '__req': 'c',
            'fb_dtsg': 'AQEkxiOYhtrJ', # инпут в теле документа
            'ttstamp': '26581716611911872109105876676',
            '__rev': '1713404',
        }

    def __init__(self, parent):
        super().__init__(parent)
        self.set_url('http://google.ru')
        conn = QNetworkAccessManager()
        self.conn = conn
        self.r = QNetworkRequest()
        self.r.attribute(QNetworkRequest.CookieSaveControlAttribute, QVariant(True))
        # self.r.setHeader(QNetworkRequest.ContentTypeHeader, "application/x-www-form-urlencoded")
        # self.r.setRawHeader("Referer", "http://www.facebook.com/")
        # self.r.setRawHeader("Host", "www.facebook.com")
        self.cj = QNetworkCookieJar()
        conn.setCookieJar(self.cj)
        conn.createRequest = self._create_request
        self.wv = WebView()
        self.wv.show()
        self.wv.page().setNetworkAccessManager(conn)
        # self.wv.auth()
        self.loop = QEventLoop()
        pass

    def _create_request(self, operation, request, data):
        # print(data)
        reply = QNetworkAccessManager.createRequest(self.conn,
                                                    operation,
                                                    request,
                                                    data)
        self.conn.new_reply = reply
        self.wv_reply = reply
        return reply

    def set_url(self, url):
        if isinstance(url, QByteArray):
            self.url = QUrl().fromEncoded(url)
        else:
            self.url = QUrl(url)

    def send_request(self, post=None, data={}):
        loop = QEventLoop()
        self.r.setUrl(self.url)
        if post:
            encoded_data = self._urlencode_post_data(data)
            pprint(encoded_data)
            self.reply_post = self.conn.post(self.r, encoded_data)
            self.reply_post.downloadProgress.connect(self.prepare_responce)

        else:
            self.reply = self.conn.get(self.r)
            self.reply.finished.connect(self.prepare_responce)
        # return \
        loop.exec()

    def prepare_responce(self):
        # self.check_redirect()
        self.responce = self.reply_post.readAll()#.data().decode('utf-8')
        pprint(self.responce)
        sys.exit()

    def check_redirect(self):
        print(self.url)
        a = self.reply.rawHeader('Location')

        if len(a) > 0:
            self.set_url(a)
            self.send_request()
        else:
            self.loop.exit()

    def test(self):
        self.wv.auth('https://www.facebook.com/freelanceuidesignerdeveloper')
        self.wv.authentication.connect(self.webview_login)

    def _urlencode_post_data(self, post_data):
        post_params = []
        for (key, value) in post_data.items():
            print(key, value)
            post_params.append(key+'='+value)
        return '&'.join(post_params)

    def webview_login(self):
        text_page = self.wv.page().mainFrame().toHtml()
        data = {
            'ft_ent_identifier': '735272899920440',
            'comment_text': 'amazing',
            'source': '22',
            'client_id': '1429632677205%3A3425397009',
            'reply_fbid': '',
            'parent_comment_id': '',
            'rootid': 'u_ps_0_0_o',
            'clp': '',
            'attached_sticker_fbid': '0',
            'attached_photo_fbid': '0',
            'feed_context': '%7B%22fbfeed_context%22%3Atrue%2C%22location_type%22%3A36%2C%22is_starred%22%3Afalse%2C%22is_pinned_post%22%3Afalse%2C%22can_moderate_timeline_story%22%3Afalse%2C%22profile_id%22%3A308106089303792%2C%22outer_object_element_id%22%3A%22u_ps_0_0_0%22%2C%22object_element_id%22%3A%22u_ps_0_0_0%22%2C%22is_ad_preview%22%3Afalse%2C%22is_editable%22%3Afalse%7D',
            'ft[tn]': '[]',
            'ft[top_level_post_id]': '',
            'ft[fbfeed_location]': '36',
            'nctr[_mod]': 'pagelet_timeline_main_column',
            'av': '100009110845526',
            '__user': '******',
            '__a': '1',
            '__dyn': '', #пустой
            '__req': 'c',
            'fb_dtsg': 'AQEkxiOYhtrJ', # инпут в теле документа
            'ttstamp': '26581716611911872109105876676',
            '__rev': '1713404',
        }
        dtsg_index = text_page.find('"token":"AQ')
        data['fb_dtsg'] = text_page[dtsg_index+9:dtsg_index+21]
        data['ttstamp'] = self.ttstamp_gen(data['fb_dtsg'])
        data['ft_ent_identifier'] = '849713745045784' # self.get_post_id(post_object)
        data['comment_text'] = random_number.choice(config.comments_list)
        pprint(data['comment_text'])


        # data['av'] = data['__user'] = from_user
        # self.applyMetaData()
        self.url = QUrl('https://www.facebook.com/ajax/ufi/add_comment.php')
        self.send_request(True, data)
        sys.exit()


    def applyMetaData(self):
        print('applyMetaData')
        raw_header = {
            'Host': 'www.facebook.com',
            'User-Agent': ' Mozilla/5.0 (X11; Linux x86_64; rv:37.0) Gecko/20100101 Firefox/37.0',
            'Accept': ' text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Accept-Language': ' en-US,en;q=0.5',
            'Content-Type': ' application/x-www-form-urlencoded; charset=UTF-8',
            'Referer': ' https://www.facebook.com/SoftProposal?fref=nf',
        }
        for (key, header) in raw_header.items():
            self.r.setRawHeader(key, header)

    @staticmethod
    def ttstamp_gen(fb_dtsg):
        u = ''
        for v in fb_dtsg:
            u += str(ord(v))
        return '2'+u
    @staticmethod
    def get_post_id(post):
        if post.object_id:
            return post.object_id
        else:
            str = post.id.split('_')
            if len(str) > 1:
                return str[0]
            else:
                post.id
Пример #4
0
class Window(QDialog):

	Move			 = 0b0000
	ResizeTop		 = 0b0001
	ResizeRight		 = 0b0010
	ResizeBottom	 = 0b0100
	ResizeLeft		 = 0b1000

	onshow			 = pyqtSignal()
	onhide			 = pyqtSignal()
	onfocus			 = pyqtSignal()
	onblur			 = pyqtSignal()
	onclose			 = pyqtSignal()
	onmove			 = pyqtSignal(int, int, int, int)
	onresize		 = pyqtSignal(int, int, int, int)
	onstatechange	 = pyqtSignal()
	onmouseenter	 = pyqtSignal()
	onmouseleave	 = pyqtSignal()

	def __init__(self, parent = None, url = '', width = None, height = None, isDialog = False):
		super(Window, self).__init__(parent if isDialog else None)
		assets.windows.append(self)
		if width is None:
			width = assets.manifest['width']
		if height is None:
			height = assets.manifest['height']
		windowFlags = Qt.WindowTitleHint | Qt.WindowSystemMenuHint | Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowCloseButtonHint
		if isDialog:
			windowFlags |= Qt.Dialog
		else:
			windowFlags |= Qt.CustomizeWindowHint
		self.dragParams = {'type': 0, 'x': 0, 'y': 0, 'size': 5, 'margin': 0, 'draging': False}
		self.webView = WebView(self, url)
		self.api = API(self)
		self.parent = parent
		self.resize(width, height)
		self.setMouseTracking(True)
		self.setWindowFlags(windowFlags)
		self.setWindowTitle('Hybrid App Engine')
		self.setAttribute(Qt.WA_QuitOnClose, True)
		self.setAttribute(Qt.WA_DeleteOnClose, True)
		self.setAttribute(Qt.WA_TranslucentBackground, True)
		self.setVisible(assets.manifest['visible'])
		self.setResizable(assets.manifest['resizable'])
		self.setFrameless(assets.manifest['frameless'])
		self.setWindowIcon(QIcon(assets.manifest['icon']))
		self.setTransBackground(assets.manifest['transBackground'])

	# Methods

	def setWindowFlags(self, windowFlags):
		visible = self.isVisible()
		super(Window, self).setWindowFlags(windowFlags)
		if visible:
			self.show()

	def testWindowFlags(self, windowFlags):
		return self.windowFlags() & windowFlags

	def getCursorType(self, x, y):
		width = self.width()
		height = self.height()
		size = self.dragParams['size']
		margin = self.dragParams['margin']
		isResizableX = self.isResizableX()
		isResizableY = self.isResizableY()
		cursorType = Window.Move
		if x >= margin and x <= width - margin and y >= margin and y <= height - margin:
			if y <= size + margin and isResizableY:
				cursorType |= Window.ResizeTop
			elif y >= height - margin - size and isResizableY:
				cursorType |= Window.ResizeBottom
			if x <= size + margin and isResizableX:
				cursorType |= Window.ResizeLeft
			elif x >= width - margin - size and isResizableX:
				cursorType |= Window.ResizeRight
		return cursorType

	# Slots

	# 获取父窗口
	@pyqtSlot(result = QObject)
	def opener(self):
		return self.parent

	# 任务栏闪烁
	@pyqtSlot()
	@pyqtSlot(int)
	def alert(self, msec = 0):
		QApplication.alert(self, msec)

	# 执行简单的JS
	@pyqtSlot(str, result = QObject)
	def eval(self, javaScript):
		obj = QObject(self)
		obj.setObjectName('evalResult')
		obj.setProperty('result', self.webView.eval(javaScript))
		print(dir(self.onstatechange))
		return obj

	# 截图
	@pyqtSlot(result = str)
	@pyqtSlot(bool, result = str)
	@pyqtSlot(bool, str, result = bool)
	def capture(self, fullScreen = False, filename = ''):
		if fullScreen:
			image = QApplication.primaryScreen().grabWindow(0)
		else:
			image = QImage(self.webView.mainFrame.contentsSize(), QImage.Format_ARGB32)
			painter = QPainter(image)
			self.webView.mainFrame.render(painter)
			painter.end()
		if filename:
			return image.save(filename)
		else:
			data = QByteArray()
			buffer = QBuffer(data)
			buffer.open(QBuffer.WriteOnly)
			image.save(buffer, 'PNG')
			return bytes(data.toBase64()).decode()

	# 打开开发者工具
	@pyqtSlot()
	def showInspector(self):
		self.webView.page().showInspector()

	# 关闭开发者工具
	@pyqtSlot()
	def hideInspector(self):
		self.webView.page().hideInspector()

	# 搜索文本
	@pyqtSlot(str, result = bool)
	def findText(self, text):
		return self.webView.page().findText(text)

	# 设置窗口图标
	@pyqtSlot(str)
	def setIcon(self, icon):
		if isinstance(icon, str):
			icon = QIcon(self.api.normUrl(icon))
		self.setWindowIcon(icon)

	# 设置内容是否已被修改(标题中需要有[*]标志)
	@pyqtSlot(bool)
	def setModified(self, modified):
		self.setWindowModified(modified)

	# 获取内容是否已被修改
	@pyqtSlot(result = bool)
	def isModified(self):
		return self.isWindowModified()

	# 设置是否模态
	@pyqtSlot(bool)
	def setModal(self, modal):
		super(Window, self).setModal(modal)

	# 获取是否模态
	@pyqtSlot(result = bool)
	def isModal(self):
		return super(Window, self).isModal()

	# 设置是否在任务栏中显示
	@pyqtSlot(bool)
	def setShowInTaskbar(self, showInTaskbar):
		if showInTaskbar:
			self.setWindowFlags(self.windowFlags() & ~ Qt.Tool)
		else:
			self.setWindowFlags(self.windowFlags() | Qt.Tool)

	# 获取是否在任务栏中显示
	@pyqtSlot(result = bool)
	def isShowInTaskbar(self):
		return self.testWindowFlags(Qt.Tool)

	# 设置窗口是否置顶
	@pyqtSlot(bool)
	def setStaysOnTop(self, staysOnTop):
		if staysOnTop:
			self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
		else:
			self.setWindowFlags(self.windowFlags() & ~ Qt.WindowStaysOnTopHint)

	# 获取窗口是否置顶
	@pyqtSlot(result = bool)
	def isStaysOnTop(self):
		return self.testWindowFlags(Qt.WindowStaysOnTopHint)

	# 设置是否显示系统边框
	@pyqtSlot(bool)
	def setFrameless(self, frameless):
		if frameless:
			self.setWindowFlags(self.windowFlags() & ~ Qt.CustomizeWindowHint & ~ Qt.WindowTitleHint | Qt.FramelessWindowHint)
		else:
			self.setWindowFlags(self.windowFlags() & ~ Qt.FramelessWindowHint | Qt.CustomizeWindowHint | Qt.WindowTitleHint)

	# 获取是否显示系统边框
	@pyqtSlot(result = bool)
	def isFrameless(self):
		return self.testWindowFlags(Qt.FramelessWindowHint)

	# 设置是否背景透明
	@pyqtSlot(bool)
	def setTransBackground(self, transBackground):
		palette = self.palette()
		if transBackground:
			palette.setBrush(QPalette.Base, Qt.transparent)
		else:
			palette.setBrush(QPalette.Base, Qt.white)
		self.setPalette(palette)

	# 获取是否背景透明
	@pyqtSlot(result = bool)
	def isTransBackground(self):
		palette = self.palette()
		return palette.brush(QPalette.Base) == Qt.transparent

	# 设置是否鼠标事件穿透
	@pyqtSlot(bool)
	def setTransMouseEvent(self, transMouseEvent):
		self.setAttribute(Qt.WA_TransparentForMouseEvents, transMouseEvent)
		self.setWindowFlags(self.windowFlags() | Qt.WindowTitleHint)

	# 获取是否是否鼠标事件穿透
	@pyqtSlot(result = bool)
	def isTransMouseEvent(self):
		return self.testAttribute(Qt.WA_TransparentForMouseEvents)

	# 设置窗口不透明度
	@pyqtSlot(float)
	def setOpacity(self, opacity):
		self.setWindowOpacity(opacity)

	# 获取窗口不透明度
	@pyqtSlot(result = float)
	def getOpacity(self):
		return self.windowOpacity()

	# 设置尺寸是否可调整
	@pyqtSlot(bool)
	def setResizable(self, resizable):
		if resizable:
			self.setMinimumSize(5, 5)
			self.setMaximumSize(0xFFFFFF, 0xFFFFFF)
		else:
			self.setFixedSize(self.width(), self.height())

	# 获取尺寸是否可调整
	@pyqtSlot(result = bool)
	def isResizable(self):
		return self.minimumSize() != self.maximumSize()

	# 设置宽度是否可调整
	@pyqtSlot(bool)
	def setResizableX(self, resizableX):
		if resizableX:
			self.setMinimumWidth(5)
			self.setMaximumWidth(0xFFFFFF)
		else:
			self.setFixedWidth(self.width())

	# 获取宽度是否可调整
	@pyqtSlot(result = bool)
	def isResizableX(self):
		return self.minimumWidth() != self.maximumWidth()

	# 设置高度是否可调整
	@pyqtSlot(bool)
	def setResizableY(self, resizableY):
		if resizableY:
			self.setMinimumHeight(5)
			self.setMaximumHeight(0xFFFFFF)
		else:
			self.setFixedHeight(self.height())

	# 获取高度是否可调整
	@pyqtSlot(result = bool)
	def isResizableY(self):
		return self.minimumHeight() != self.maximumHeight()

	# 设置是否可最小化
	@pyqtSlot(bool)
	def setMinimizable(self, minimizable):
		if minimizable:
			self.setWindowFlags(self.windowFlags() | Qt.WindowMinimizeButtonHint)
		else:
			self.setWindowFlags(self.windowFlags() & ~ Qt.WindowMinimizeButtonHint)

	# 获取是否可最小化
	@pyqtSlot(result = bool)
	def isMinimizable(self):
		return self.testWindowFlags(Qt.WindowMinimizeButtonHint)

	# 设置是否可最大化
	@pyqtSlot(bool)
	def setMaximizable(self, maximizable):
		if maximizable:
			self.setWindowFlags(self.windowFlags() | Qt.WindowMaximizeButtonHint)
		else:
			self.setWindowFlags(self.windowFlags() & ~ Qt.WindowMaximizeButtonHint)

	# 获取是否可最大化
	@pyqtSlot(result = bool)
	def isMaximizable(self):
		return self.testWindowFlags(Qt.WindowMaximizeButtonHint)

	# 设置是否可关闭
	@pyqtSlot(bool)
	def setClosable(self, closable):
		if closable:
			self.setWindowFlags(self.windowFlags() | Qt.WindowCloseButtonHint)
		else:
			self.setWindowFlags(self.windowFlags() & ~ Qt.WindowCloseButtonHint)

	# 获取是否可关闭
	@pyqtSlot(result = bool)
	def isClosable(self):
		return self.testWindowFlags(Qt.WindowCloseButtonHint)

	# 获取是否已最小化
	@pyqtSlot(result = bool)
	def isMinimized(self):
		return super(Window, self).isMinimized()

	# 获取是否已最大化
	@pyqtSlot(result = bool)
	def isMaximized(self):
		return super(Window, self).isMaximized()

	# 获取是否已最大化
	@pyqtSlot(result = bool)
	def isFullScreen(self):
		return super(Window, self).isFullScreen()

	# 最小化
	@pyqtSlot()
	def minimize(self):
		if self.isMinimizable():
			self.showMinimized()

	# 还原
	@pyqtSlot()
	def normalize(self):
		self.showNormal()

	# 最大化
	@pyqtSlot()
	def maximize(self):
		if self.isMaximizable():
			self.showMaximized()

	# 全屏
	@pyqtSlot()
	def showFullScreen(self):
		super(Window, self).showFullScreen()

	# 设置窗口坐标
	@pyqtSlot(int, int)
	def setPos(self, x, y):
		self.move(x, y)

	# 设置窗口尺寸
	@pyqtSlot(int, int)
	def setSize(self, width, height):
		self.resize(width, height)

	# 设置窗口最小尺寸
	@pyqtSlot(int, int)
	def setMinSize(self, width, height):
		self.setMinimumSize(width, height)

	# 设置窗口最大尺寸
	@pyqtSlot(int, int)
	def setMaxSize(self, width, height):
		self.setMaximumSize(width, height)

	# 设置尺寸控制大小
	@pyqtSlot(int)
	def setResizerSize(self, size):
		self.dragParams['size'] = size

	# 获取尺寸控制大小
	@pyqtSlot(result = int)
	def getResizerSize(self):
		return self.dragParams['size']

	# 设置尺寸控制边距
	@pyqtSlot(int)
	def setResizerMargin(self, margin):
		self.dragParams['margin'] = margin

	# 获取尺寸控制边距
	@pyqtSlot(result = int)
	def getResizerMargin(self):
		return self.dragParams['margin']

	# 是否正在拖动
	@pyqtSlot(result = bool)
	def isDraging(self):
		return self.dragParams['draging']

	# 开始拖动
	@pyqtSlot()
	def dragStart(self):
		self.dragParams['draging'] = True

	# 结束拖动
	@pyqtSlot()
	def dragStop(self):
		self.dragParams['type'] = Window.Move
		self.dragParams['draging'] = False

	# 窗口获取焦点
	@pyqtSlot()
	def activate(self):
		self.activateWindow()

	# 窗口是否已获得焦点
	@pyqtSlot(result = bool)
	def isActive(self):
		return self.isActiveWindow()

	# 设置窗口可用状态
	@pyqtSlot(bool)
	def setEnabled(self, enabled):
		super(Window, self).setEnabled(enabled)

	# 窗口是否可用
	@pyqtSlot(result = bool)
	def isEnabled(self):
		return super(Window, self).isEnabled()

	# 设置窗口可见状态
	@pyqtSlot(result = bool)
	def setVisible(self, visible):
		super(Window, self).setVisible(visible)

	# 窗口是否显示
	@pyqtSlot(result = bool)
	def isVisible(self):
		return super(Window, self).isVisible()

	# 显示窗口
	@pyqtSlot()
	def show(self):
		super(Window, self).show()

	# 隐藏窗口
	@pyqtSlot()
	def hide(self):
		super(Window, self).hide()

	# 关闭窗口
	@pyqtSlot()
	def close(self):
		super(Window, self).close()

	# Events
	def keyPressEvent(self, event):
		if(event.key() == Qt.Key_Escape):
			event.ignore()

	def mousePressEvent(self, event):
		self.dragParams['x'] = event.x()
		self.dragParams['y'] = event.y()
		self.dragParams['globalX'] = event.globalX()
		self.dragParams['globalY'] = event.globalY()
		self.dragParams['width'] = self.width()
		self.dragParams['height'] = self.height()
		if self.dragParams['type'] != Window.Move and self.isFrameless() and not self.isMaximized() and not self.isFullScreen():
			self.dragStart()

	def mouseReleaseEvent(self, event):
		self.dragStop()

	def mouseMoveEvent(self, event):

		if self.isFrameless() and not self.isMaximized() and not self.isFullScreen():
			# 判断鼠标类型
			cursorType = self.dragParams['type']
			if not self.dragParams['draging']:
				cursorType = self.dragParams['type'] = self.getCursorType(event.x(), event.y())

			# 设置鼠标形状
			if cursorType in (Window.ResizeTop, Window.ResizeBottom):
				self.webView.setCursor(Qt.SizeVerCursor)
			elif cursorType in (Window.ResizeLeft, Window.ResizeRight):
				self.webView.setCursor(Qt.SizeHorCursor)
			elif cursorType in (Window.ResizeTop | Window.ResizeRight, Window.ResizeLeft | Window.ResizeBottom):
				self.webView.setCursor(Qt.SizeBDiagCursor)
			elif cursorType in (Window.ResizeTop | Window.ResizeLeft, Window.ResizeRight | Window.ResizeBottom):
				self.webView.setCursor(Qt.SizeFDiagCursor)
			elif self.dragParams['draging']:
				self.webView.setCursor(Qt.ArrowCursor)

		# 判断窗口拖动
		dragType = self.dragParams['type']
		if self.dragParams['draging'] and not self.isMaximized() and not self.isFullScreen():
			x = self.x()
			y = self.y()
			width = self.width()
			height = self.height()
			if dragType == Window.Move:
				x = event.globalX() - self.dragParams['x']
				y = event.globalY() - self.dragParams['y']
			elif self.isFrameless():
				if dragType & Window.ResizeTop == Window.ResizeTop:
					y = event.globalY() - self.dragParams['margin']
					height = self.dragParams['height'] + self.dragParams['globalY'] - event.globalY()
				elif dragType & Window.ResizeBottom == Window.ResizeBottom:
					height = self.dragParams['height'] - self.dragParams['globalY'] + event.globalY()
				if dragType & Window.ResizeLeft == Window.ResizeLeft:
					x = event.globalX() - self.dragParams['margin']
					width = self.dragParams['width'] + self.dragParams['globalX'] - event.globalX()
				elif dragType & Window.ResizeRight == Window.ResizeRight:
					width = self.dragParams['width'] - self.dragParams['globalX'] + event.globalX()
			else:
				return

			if width < self.minimumWidth():
				width = self.minimumWidth()
			elif width > self.maximumWidth():
				width = self.maximumWidth()
			if height < self.minimumHeight():
				height = self.minimumHeight()
			elif height > self.maximumHeight():
				height = self.maximumHeight()

			self.setGeometry(x, y, width, height)

	def changeEvent(self, event):
		if event.type() == QEvent.ActivationChange:
			if self.isActiveWindow():
				self.onfocus.emit()
			else:
				self.onblur.emit()
		elif event.type() == QEvent.WindowStateChange:
			self.onstatechange.emit()

	def resizeEvent(self, event):
		size = event.size()
		oldSize = event.oldSize()
		self.onresize.emit(size.width(), size.height(), oldSize.width(), oldSize.height())
		self.webView.resize(super(Window, self).size())

	def moveEvent(self, event):
		pos = event.pos()
		oldPos = event.oldPos()
		self.onmove.emit(pos.x(), pos.y(), oldPos.x(), oldPos.y())

	def enterEvent(self, event):
		self.onmouseenter.emit()

	def leaveEvent(self, event):
		self.onmouseleave.emit()

	def showEvent(self, event):
		self.onshow.emit()

	def hideEvent(self, event):
		self.onhide.emit()

	def closeEvent(self, event):
		self.onclose.emit()
		if self.isClosable():
			self.webView.close()
			assets.windows = [i for i in assets.windows if i != self]
			event.accept()
		else:
			event.ignore()