PyQt5 QTabWidget 显示 currentWidget() "NoneType"
PyQt5 QTabWidget showing currentWidget() "NoneType"
我正在使用 python、PyQt5 QWebEnjineView 构建一个简单的浏览器。
我想让重新加载按钮在页面加载时隐藏,而“停止加载”按钮可见,
加载完成后,重新加载按钮将再次可见,“停止加载”按钮将隐藏。
我的 QWebEnjineView 在一个名为 add_new_tab 的方法中,我在 init[=29 中将 QTabWidget 定义为 self.tabs =]方法。
import os
import sys
from PyQt5 import QtGui
from PyQt5 import QtCore
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import QWebEngineView
class mainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(mainWindow, self).__init__()
# create tabs
self.tabs = QTabWidget()
self.tabs.tabBarDoubleClicked.connect(self.tab_open_doubleclick)
self.tabs.setTabsClosable(True)
self.tabs.tabCloseRequested.connect(self.close_current_tab)
self.tabs.currentWidget().loadProgress.connect(self.loadProgressHandler)
self.tabs.currentWidget().loadFinished.connect(self.loadFinishedHandler)
self.setCentralWidget(self.tabs)
# self.setCentralWidget(self.browser)
self.showMaximized()
# nav bar
self.navbar = QToolBar()
self.navbar.setMovable(False)
self.addToolBar(self.navbar)
# Refresh button
self.reload_butn = QPushButton(self, text="Reload")
self.reload_butn.clicked.connect(self.reload_tab)
# Set reload button visible
self.reload_butn.setHidden(False)
# Stop button
self.stop_btn = QPushButton(self, text="Stop")
self.stop_btn.clicked.connect(self.stop_loading_tab)
self.stop_btn.setHidden(True)
# Set stop_butn hidden initially
self.stop_btn.setHidden(True)
# Add Refresh and Stop button
self.navbar.addWidget(self.stop_btn)
self.navbar.addWidget(self.reload_butn)
# Add Address bar
self.url_bar = QLineEdit()
self.url_bar.returnPressed.connect(self.navigate_to_url)
self.navbar.addWidget(self.url_bar)
# on startup
self.add_new_tab(QUrl("https://www.google.com/"), "Homepage")
self.show()
@QtCore.pyqtSlot(int)
def loadProgressHandler(self, prog):
self.stop_btn.setHidden(False) # When any page is loading, then stop_butn will visible
self.reload_butn.setHidden(True) # When any page is loading, then reload_butn will hidde
@QtCore.pyqtSlot()
def loadFinishedHandler(self):
self.reload_butn.setHidden(False) # When loading is finished, then reload_butn will be visible again for the user
self.stop_btn.setHidden(True) # When load finished, stop button will be hidden
# reload tab
def reload_tab(self):
self.tabs.currentWidget().reload()
def stop_loading_tab(self):
self.tabs.currentWidget().stop()
def close_current_tab(self, i):
if self.tabs.count() < 2 :
return
self.tabs.removeTab(i)
# stop load current tab
def stop_loading_tab(self):
self.tabs.currentWidget().stop()
# doubleclick on empty space for new tab
def tab_open_doubleclick(self, i):
if i == -1: # No tab under the click
self.add_new_tab(QUrl("http://www.google.com/"), label="New tab")
# function to add new tab
def add_new_tab(self, qurl=None, label="Blank"):
if qurl is None:
qurl = QUrl('https://www.google.com/')
browser = QWebEngineView()
browser.setUrl(qurl)
i = self.tabs.addTab(browser, label)
self.tabs.setCurrentIndex(i)
def navigate_to_url(self):
self.tabs.currentWidget().setUrl(QUrl(self.url_bar.text()))
app = QApplication(sys.argv)
app.setApplicationName("browser")
window = mainWindow()
app.exec_()
我有一些用于重新加载、返回、主页等的按钮,例如我在重新加载方法中调用了 self.tabs.currentWidget().reload()
,
但是当我添加 self.tabs.currentWidget().loadProgress.connect(self.loadProgressHandler)
对于操作,然后它给了我一个错误
self.tabs.currentWidget().loadProgress.connect(self.loadProgressHandler)
AttributeError: 'NoneType' object has no attribute 'loadProgress'
谁能告诉我为什么显示 self.tabs.currentWidget() 是 NoneType?
有办法解决吗?问我是否需要更多详细信息
谢谢!
错误原因是:
self.tabs.currentWidget().loadProgress.connect(self.loadProgressHandler)
self.tabs.currentWidget().loadFinished.connect(self.loadFinishedHandler)
OP 假设连接将与所有页面发生,这是不正确的,因为它只会与当前小部件一起发生,在这种情况下 None 导致错误。
在这种情况下,解决方案是连接每个创建的 QWebEngineView 并在 sender() 与 currentWidget() 匹配时检查插槽。
移除
self.tabs.currentWidget().loadProgress.connect(self.loadProgressHandler)
self.tabs.currentWidget().loadFinished.connect(self.loadFinishedHandler)
添加连接:
def add_new_tab(self, qurl=None, label="Blank"):
if qurl is None:
qurl = QUrl('https://www.google.com/')
browser = QWebEngineView()
browser.loadProgress.connect(self.loadProgressHandler)
browser.loadFinished.connect(self.loadFinishedHandler)
i = self.tabs.addTab(browser, label)
self.tabs.setCurrentIndex(i)
browser.load(qurl)
验证:
@QtCore.pyqtSlot(int)
def loadProgressHandler(self, prog):
if self.tabs.currentWidget() is not self.sender():
return
self.stop_btn.show()
self.reload_butn.hide()
@QtCore.pyqtSlot()
def loadFinishedHandler(self):
if self.tabs.currentWidget() is not self.sender():
return
self.reload_butn.show()
self.stop_btn.hide()
更新:
存在以下错误:
添加到 QToolBar 的小部件的可见性使用关联的 QAction 进行管理。
与其管理与加载进度和完成相关联的 2 个槽,不如只使用其中一个槽,因为例如,关联的槽在加载到 100% 时也会被调用,所以它可以隐藏,因为它可以与 finished 一起调用。
最好验证可以None的变量,避免异常
综合以上,解决方案是:
import sys
from PyQt5.QtCore import pyqtSlot, QUrl
from PyQt5.QtWidgets import (
QApplication,
QLineEdit,
QMainWindow,
QPushButton,
QTabWidget,
QToolBar,
)
from PyQt5.QtWebEngineWidgets import QWebEngineView
class mainWindow(QMainWindow):
def __init__(self, parent=None):
super(mainWindow, self).__init__(parent)
self.tabs = QTabWidget(tabsClosable=True)
self.tabs.tabBarDoubleClicked.connect(self.tab_open_doubleclick)
self.tabs.tabCloseRequested.connect(self.close_current_tab)
self.navbar = QToolBar(movable=True)
self.addToolBar(self.navbar)
self.reload_butn = QPushButton(self, text="Reload")
self.reload_butn.clicked.connect(self.reload_tab)
self.stop_btn = QPushButton(self, text="Stop")
self.stop_btn.clicked.connect(self.stop_loading_tab)
self.url_bar = QLineEdit()
self.url_bar.returnPressed.connect(self.navigate_to_url)
self.stop_action = self.navbar.addWidget(self.stop_btn)
self.reload_action = self.navbar.addWidget(self.reload_butn)
self.navbar.addWidget(self.url_bar)
self.stop_action.setVisible(False)
self.add_new_tab(QUrl("https://www.google.com/"), "Homepage")
self.setCentralWidget(self.tabs)
self.showMaximized()
@pyqtSlot(int)
def loadProgressHandler(self, prog):
if self.tabs.currentWidget() is not self.sender():
return
loading = prog < 100
self.stop_action.setVisible(loading)
self.reload_action.setVisible(not loading)
def reload_tab(self):
self.tabs.currentWidget().reload()
def stop_loading_tab(self):
self.tabs.currentWidget().stop()
def close_current_tab(self, i):
if self.tabs.count() < 2:
return
self.tabs.removeTab(i)
def stop_loading_tab(self):
if self.tabs.currentWidget() is None:
return
self.tabs.currentWidget().stop()
def tab_open_doubleclick(self, i):
if i == -1:
self.add_new_tab(QUrl("http://www.google.com/"), label="New tab")
def add_new_tab(self, qurl=None, label="Blank"):
if qurl is None:
qurl = QUrl("https://www.google.com/")
browser = QWebEngineView()
browser.loadProgress.connect(self.loadProgressHandler)
i = self.tabs.addTab(browser, label)
self.tabs.setCurrentIndex(i)
browser.load(qurl)
def navigate_to_url(self):
if self.tabs.currentWidget() is None:
return
self.tabs.currentWidget().load(QUrl.fromString(self.url_bar.text()))
def main():
app = QApplication(sys.argv)
app.setApplicationName("browser")
window = mainWindow()
app.exec_()
if __name__ == "__main__":
main()
我正在使用 python、PyQt5 QWebEnjineView 构建一个简单的浏览器。
我想让重新加载按钮在页面加载时隐藏,而“停止加载”按钮可见, 加载完成后,重新加载按钮将再次可见,“停止加载”按钮将隐藏。
我的 QWebEnjineView 在一个名为 add_new_tab 的方法中,我在 init[=29 中将 QTabWidget 定义为 self.tabs =]方法。
import os
import sys
from PyQt5 import QtGui
from PyQt5 import QtCore
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import QWebEngineView
class mainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(mainWindow, self).__init__()
# create tabs
self.tabs = QTabWidget()
self.tabs.tabBarDoubleClicked.connect(self.tab_open_doubleclick)
self.tabs.setTabsClosable(True)
self.tabs.tabCloseRequested.connect(self.close_current_tab)
self.tabs.currentWidget().loadProgress.connect(self.loadProgressHandler)
self.tabs.currentWidget().loadFinished.connect(self.loadFinishedHandler)
self.setCentralWidget(self.tabs)
# self.setCentralWidget(self.browser)
self.showMaximized()
# nav bar
self.navbar = QToolBar()
self.navbar.setMovable(False)
self.addToolBar(self.navbar)
# Refresh button
self.reload_butn = QPushButton(self, text="Reload")
self.reload_butn.clicked.connect(self.reload_tab)
# Set reload button visible
self.reload_butn.setHidden(False)
# Stop button
self.stop_btn = QPushButton(self, text="Stop")
self.stop_btn.clicked.connect(self.stop_loading_tab)
self.stop_btn.setHidden(True)
# Set stop_butn hidden initially
self.stop_btn.setHidden(True)
# Add Refresh and Stop button
self.navbar.addWidget(self.stop_btn)
self.navbar.addWidget(self.reload_butn)
# Add Address bar
self.url_bar = QLineEdit()
self.url_bar.returnPressed.connect(self.navigate_to_url)
self.navbar.addWidget(self.url_bar)
# on startup
self.add_new_tab(QUrl("https://www.google.com/"), "Homepage")
self.show()
@QtCore.pyqtSlot(int)
def loadProgressHandler(self, prog):
self.stop_btn.setHidden(False) # When any page is loading, then stop_butn will visible
self.reload_butn.setHidden(True) # When any page is loading, then reload_butn will hidde
@QtCore.pyqtSlot()
def loadFinishedHandler(self):
self.reload_butn.setHidden(False) # When loading is finished, then reload_butn will be visible again for the user
self.stop_btn.setHidden(True) # When load finished, stop button will be hidden
# reload tab
def reload_tab(self):
self.tabs.currentWidget().reload()
def stop_loading_tab(self):
self.tabs.currentWidget().stop()
def close_current_tab(self, i):
if self.tabs.count() < 2 :
return
self.tabs.removeTab(i)
# stop load current tab
def stop_loading_tab(self):
self.tabs.currentWidget().stop()
# doubleclick on empty space for new tab
def tab_open_doubleclick(self, i):
if i == -1: # No tab under the click
self.add_new_tab(QUrl("http://www.google.com/"), label="New tab")
# function to add new tab
def add_new_tab(self, qurl=None, label="Blank"):
if qurl is None:
qurl = QUrl('https://www.google.com/')
browser = QWebEngineView()
browser.setUrl(qurl)
i = self.tabs.addTab(browser, label)
self.tabs.setCurrentIndex(i)
def navigate_to_url(self):
self.tabs.currentWidget().setUrl(QUrl(self.url_bar.text()))
app = QApplication(sys.argv)
app.setApplicationName("browser")
window = mainWindow()
app.exec_()
我有一些用于重新加载、返回、主页等的按钮,例如我在重新加载方法中调用了 self.tabs.currentWidget().reload()
,
但是当我添加 self.tabs.currentWidget().loadProgress.connect(self.loadProgressHandler)
对于操作,然后它给了我一个错误
self.tabs.currentWidget().loadProgress.connect(self.loadProgressHandler)
AttributeError: 'NoneType' object has no attribute 'loadProgress'
谁能告诉我为什么显示 self.tabs.currentWidget() 是 NoneType? 有办法解决吗?问我是否需要更多详细信息
谢谢!
错误原因是:
self.tabs.currentWidget().loadProgress.connect(self.loadProgressHandler)
self.tabs.currentWidget().loadFinished.connect(self.loadFinishedHandler)
OP 假设连接将与所有页面发生,这是不正确的,因为它只会与当前小部件一起发生,在这种情况下 None 导致错误。
在这种情况下,解决方案是连接每个创建的 QWebEngineView 并在 sender() 与 currentWidget() 匹配时检查插槽。
移除
self.tabs.currentWidget().loadProgress.connect(self.loadProgressHandler) self.tabs.currentWidget().loadFinished.connect(self.loadFinishedHandler)
添加连接:
def add_new_tab(self, qurl=None, label="Blank"): if qurl is None: qurl = QUrl('https://www.google.com/') browser = QWebEngineView() browser.loadProgress.connect(self.loadProgressHandler) browser.loadFinished.connect(self.loadFinishedHandler) i = self.tabs.addTab(browser, label) self.tabs.setCurrentIndex(i) browser.load(qurl)
验证:
@QtCore.pyqtSlot(int) def loadProgressHandler(self, prog): if self.tabs.currentWidget() is not self.sender(): return self.stop_btn.show() self.reload_butn.hide() @QtCore.pyqtSlot() def loadFinishedHandler(self): if self.tabs.currentWidget() is not self.sender(): return self.reload_butn.show() self.stop_btn.hide()
更新:
存在以下错误:
添加到 QToolBar 的小部件的可见性使用关联的 QAction 进行管理。
与其管理与加载进度和完成相关联的 2 个槽,不如只使用其中一个槽,因为例如,关联的槽在加载到 100% 时也会被调用,所以它可以隐藏,因为它可以与 finished 一起调用。
最好验证可以None的变量,避免异常
综合以上,解决方案是:
import sys
from PyQt5.QtCore import pyqtSlot, QUrl
from PyQt5.QtWidgets import (
QApplication,
QLineEdit,
QMainWindow,
QPushButton,
QTabWidget,
QToolBar,
)
from PyQt5.QtWebEngineWidgets import QWebEngineView
class mainWindow(QMainWindow):
def __init__(self, parent=None):
super(mainWindow, self).__init__(parent)
self.tabs = QTabWidget(tabsClosable=True)
self.tabs.tabBarDoubleClicked.connect(self.tab_open_doubleclick)
self.tabs.tabCloseRequested.connect(self.close_current_tab)
self.navbar = QToolBar(movable=True)
self.addToolBar(self.navbar)
self.reload_butn = QPushButton(self, text="Reload")
self.reload_butn.clicked.connect(self.reload_tab)
self.stop_btn = QPushButton(self, text="Stop")
self.stop_btn.clicked.connect(self.stop_loading_tab)
self.url_bar = QLineEdit()
self.url_bar.returnPressed.connect(self.navigate_to_url)
self.stop_action = self.navbar.addWidget(self.stop_btn)
self.reload_action = self.navbar.addWidget(self.reload_butn)
self.navbar.addWidget(self.url_bar)
self.stop_action.setVisible(False)
self.add_new_tab(QUrl("https://www.google.com/"), "Homepage")
self.setCentralWidget(self.tabs)
self.showMaximized()
@pyqtSlot(int)
def loadProgressHandler(self, prog):
if self.tabs.currentWidget() is not self.sender():
return
loading = prog < 100
self.stop_action.setVisible(loading)
self.reload_action.setVisible(not loading)
def reload_tab(self):
self.tabs.currentWidget().reload()
def stop_loading_tab(self):
self.tabs.currentWidget().stop()
def close_current_tab(self, i):
if self.tabs.count() < 2:
return
self.tabs.removeTab(i)
def stop_loading_tab(self):
if self.tabs.currentWidget() is None:
return
self.tabs.currentWidget().stop()
def tab_open_doubleclick(self, i):
if i == -1:
self.add_new_tab(QUrl("http://www.google.com/"), label="New tab")
def add_new_tab(self, qurl=None, label="Blank"):
if qurl is None:
qurl = QUrl("https://www.google.com/")
browser = QWebEngineView()
browser.loadProgress.connect(self.loadProgressHandler)
i = self.tabs.addTab(browser, label)
self.tabs.setCurrentIndex(i)
browser.load(qurl)
def navigate_to_url(self):
if self.tabs.currentWidget() is None:
return
self.tabs.currentWidget().load(QUrl.fromString(self.url_bar.text()))
def main():
app = QApplication(sys.argv)
app.setApplicationName("browser")
window = mainWindow()
app.exec_()
if __name__ == "__main__":
main()