zoukankan      html  css  js  c++  java
  • PyQt5 接入 web 登录页

    PyQt5 接入 web 登录页

    概述

    一个桌面软件一般都会有登录后的操作, 用 PyQt 写一套登录页面工作量还不小,出了处理登录逻辑外,还要关心验证码,错误提示,跳转到注册页面等等. 如果已经有了一个 web 版的登录页,那我们又何必再写一套呢?

    原理

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

    流程

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

    代码

    main.py

    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.py

    # -*- 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.py

    # -*- 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.py

    cookies = {}
    

    预览图

  • 相关阅读:
    二维RMQ问题
    乘法逆元的一些求法
    对于一些小的数学的方法的一些记录
    第一次举办比赛记
    牛客网比赛-Wannafly挑战赛27
    [HEOI2012]Akai的数学作业-题解
    线性基简单学习笔记
    1978 Fibonacci数列 3
    1076 排序
    1205 单词翻转
  • 原文地址:https://www.cnblogs.com/aloe-n/p/11484457.html
Copyright © 2011-2022 走看看