PyQt5 接入 web 登陆页

PyQt5 接入 web 登陆页

概述

一个桌面软件通常都会有登陆后的操做, 用 PyQt 写一套登陆页面工做量还不小,出了处理登陆逻辑外,还要关心验证码,错误提示,跳转到注册页面等等. 若是已经有了一个 web 版的登陆页,那咱们又何须再写一套呢?python

原理

  • 用 QWebEngineView 嵌入登陆页;
  • 利用 QWebEngineView 的 runJavaScript 方法获取 cookies;
  • 利用子线程扫描指定 cookie,一旦获取到,则切换到主窗口.

流程

graph TD; 启动-->id0(显示登陆窗口,隐藏主窗口); id0-->id1{子线程定时检测指定cookie}; id1-->|否|id1; id1-->|是|id2(显示主窗口,隐藏登陆窗口); id2-->id3(须要从新登陆); id3-->id0;

代码

main.pyweb

import sys
import time
from threading import Thread
from PyQt5 import QtWidgets
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QApplication, QMainWindow, QAction

import context
from content import MainContent
from login import Login


class Main(QMainWindow):
    str_signal = pyqtSignal(str)

    def __init__(self):
        super().__init__()
        self.setupUi()
        self.init_signal()
        self.connect()

    def setupUi(self):
        self.resize(1000, 700)
        self.menu = self.menuBar().addMenu('User')
        self.logout_action = QAction("&Logout", self)
        self.menu.addAction(self.logout_action)

        self.centralWidget = QtWidgets.QWidget(self)
        self.setCentralWidget(self.centralWidget)

        self.grid_layout = QtWidgets.QGridLayout(self.centralWidget)
        self.grid_layout.setContentsMargins(0, 0, 0, 0)
        self.grid_layout.setSpacing(0)

        self.login_form = Login(self)
        self.main_content = MainContent(self)
        self.grid_layout.addWidget(self.login_form, 1, 1, 1, 1)
        self.grid_layout.addWidget(self.main_content, 1, 2, 1, 1)

        self.show_login()
        self.monitor_token()

    def init_signal(self):
        def func(signal):
            getattr(self, signal)()

        self.str_signal[str].connect(func)

    def connect(self):
        self.logout_action.triggered.connect(self.show_login)

    def show_login(self):
        self.login_form.logout()
        self.login_form.show()
        self.main_content.hide()

    def show_main(self):
        self.login_form.hide()
        self.main_content.show()

    def monitor_token(self):
        def func():
            while True:
                if not context.cookies.get('_accessToken'):
                    self.login_form.load_cookies()
                    time.sleep(1)
                    if context.cookies.get('_accessToken'):
                        self.str_signal.emit("show_main")

        t = Thread(target=func)
        t.setDaemon(True)
        t.start()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    ui = Main()
    ui.show()
    sys.exit(app.exec_())

login.pyjson

# -*- encoding:utf-8 -*-
from PyQt5 import QtWebEngineWidgets
from PyQt5.QtCore import QUrl
import json
import context


class Login(QtWebEngineWidgets.QWebEngineView):

    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self.setupUi()
        self.connect()

    def setupUi(self):
        self.load(QUrl('https://crm.chengfayun.com'))

    def connect(self):
        self.loadFinished.connect(self.load_cookies)

    def load_cookies(self):
        print('load cookies', self.url())

        def parse_cookies(origin):
            if origin:
                context.cookies = {item.split("=")[0]: item.split(
                    "=")[1] for item in origin.split('; ')}

        self.page().runJavaScript('document.cookie', parse_cookies)

    def logout(self):
        self.page().profile().cookieStore().deleteAllCookies()
        self.reload()

    def print_cookie(self):
        print(json.dumps(self.cookies, ensure_ascii=False, indent=2))

content.pyapi

# -*- encoding:utf-8 -*-
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QTextEdit, QWidget, QPushButton
from login import Login
import context
import requests
import json


class MainContent(QWidget):

    def __init__(self, parent):
        super().__init__(parent=parent)
        self.setupUi()
        self.connect()

    def setupUi(self):
        self.grid_layout = QtWidgets.QGridLayout(self)
        self.grid_layout.setContentsMargins(0, 0, 0, 0)
        self.grid_layout.setSpacing(0)

        self.text_edit = QTextEdit(self)
        self.info_btn = QPushButton("get tenant info", self)
        self.meta_btn = QPushButton("get metas", self)
        self.grid_layout.addWidget(self.info_btn, 1, 1, 1, 1)
        self.grid_layout.addWidget(self.meta_btn, 1, 2, 1, 1)
        self.grid_layout.addWidget(self.text_edit, 2, 1, 1, 2)

    def connect(self):
        self.meta_btn.clicked.connect(self.get_metas)
        self.info_btn.clicked.connect(self.get_info)

    def http_get(self, url):
        return requests.get(url, headers={'x-token': context.cookies.get('_accessToken')}).json()

    def get_metas(self):
        res = self.http_get("https://crm.chengfayun.com/api/v1.0/one/all-metas")
        self.text_edit.setText(json.dumps(res, ensure_ascii=False, indent=4))

    def get_info(self):
        url = f"https://crm.chengfayun.com/api/v1.0/tenant-gateway/tenant/org/{context.cookies.get('_tenant_id')}"
        res = self.http_get(url)
        self.text_edit.setText(json.dumps(res, ensure_ascii=False, indent=4))

context.pycookie

cookies = {}

预览图

相关文章
相关标签/搜索