【发布时间】:2019-08-10 05:44:48
【问题描述】:
我对 PyQt 还很陌生,我已经设法通过使用 Qt Designer 组合一个工作应用程序来摸索自己的方式。但是,我需要添加一个 OAuth2 流来登录特定服务,但我无法让它适应我现有的应用程序。
我在 Github (https://github.com/alonraiz/QT-OAuth-Example) 中找到了一个处理 PyQt5/OAuth2 登录的好例子——只要我独立运行它。我现在正在尝试集成它,以便在用户选择特定菜单项时弹出它......我遇到了麻烦。
默认代码使用这个:
app = QApplication(sys.argv)
browser = LoginWindow(app)
由于我已经有一个应用程序,所以我尝试调用:
browser = LoginWindow(app)
使用我现有的应用程序对象。然后让我遇到这个错误: QCoreApplication::exec: 事件循环已经在运行
这似乎是有道理的。所以我删除了这个:
sys.exit(app.exec_())
然后我什么也得不到。
根据我有限的 PyQt5 经验,我确定我的做法完全错误......
这是一个说明我现在所处位置的示例。感谢任何帮助!
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'test.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!
import sys
from urllib.parse import urlencode, parse_qs
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor
from PyQt5.QtCore import QUrl
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QApplication
"""
login anxious-elephant@example.com
password Frantic-Magpie-Tame-Cow-9
"""
ClientId = '0oamu4rr08hdGKd9u0h7'
RedirectUrl = 'www.oauth.com/playground/authorization-code.html'
RedirectScheme = 'https://'
Scopes = ['photo offline_access']
ResponseType = 'code'
Headers = {'client_id': ClientId, 'redirect_uri': RedirectScheme+RedirectUrl, 'response_type': ResponseType,
'scope': str.join(' ', Scopes), 'state': 'RT6TfGb4jEWbz7SI'}
AuthUrl = 'https://dev-396343.oktapreview.com/oauth2/default/v1/authorize?{headers}'.format(
headers=urlencode(Headers))
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(234, 167)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 234, 22))
self.menubar.setObjectName("menubar")
self.menuFile = QtWidgets.QMenu(self.menubar)
self.menuFile.setObjectName("menuFile")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.actionLogin = QtWidgets.QAction(MainWindow)
self.actionLogin.setObjectName("actionLogin")
self.menuFile.addAction(self.actionLogin)
self.menubar.addAction(self.menuFile.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.menuFile.setTitle(_translate("MainWindow", "File"))
self.actionLogin.setText(_translate("MainWindow", "Login"))
class RequestInterceptor(QWebEngineUrlRequestInterceptor):
def __init__(self, app):
super(RequestInterceptor, self).__init__()
self.app = app
def interceptRequest(self, info):
if RedirectUrl == (info.requestUrl().host()+info.requestUrl().path()):
params = parse_qs(info.requestUrl().query())
if 'code' in params.keys():
print('OAuth code is {code}'.format(code=params['code']))
self.app.quit()
# return params['code']
class LoginWindow(QWebEngineView):
logged_in = QtCore.pyqtSignal(['QString'])
def __init__(self, app):
super(LoginWindow, self).__init__()
self.nam = self.page()
self.app = app
self.setUrl(QUrl(AuthUrl))
self.show()
self.loadFinished.connect(self._loadFinished)
interceptor = RequestInterceptor(app)
self.page().profile().setUrlRequestInterceptor(interceptor)
# This needs enabled to get the working example running:
# sys.exit(app.exec_())
def _loadFinished(self, result):
self.page().toHtml(self.callable)
def callable(self, data):
self.html = data
class MainMenu(Ui_MainWindow):
def __init__(self, dialog, mainapp):
global fn
Ui_MainWindow.__init__(self)
self.setupUi(dialog)
self.actionLogin.triggered.connect(self.login)
self.mainapp = mainapp
def login(self):
print("login")
browser = LoginWindow(self.mainapp)
if __name__ == "__main__":
# This doesn't work
app = QtWidgets.QApplication(sys.argv)
menu = QtWidgets.QMainWindow()
prog = MainMenu(menu, app)
menu.show()
sys.exit(app.exec_())
# This works:
# app = QApplication(sys.argv)
# browser = LoginWindow(app)
我想做的是让 OAuth 流作为主应用程序的弹出窗口工作,而不是一个独立的应用程序(或者让两个应用程序和平共处)。
【问题讨论】:
标签: python python-3.x oauth-2.0 pyqt5