I want the following code to get the request url starting with http://down.51en.com:88 during the web loading process , and then do other processing with the response object of the url .
In my program, once targetUrl is assigned a value , I want the function targetUrlGetter(url) to return it to the caller, however , the problem is that QApplication::exec() enters the main event loop so cannot execute code at the end of thetargetUrlGetter() function after the exec() call , thus the function cannot return , I have tried with qApp.quit() in interceptRequest(self, info) in order to tell the application to exit so that targetUrlGetter(url) can return , but the function still cannot return and the program even crashes on exit(tested on Win7 32bit), so how can I return the targetUrl to the caller program ?
The difficulties here are how to exit the Qt event loop without crash and return the request url to the caller.
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtWebEngineCore import *
from PyQt5.QtCore import *
class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
def __init__(self, parent=None):
super().__init__(parent)
self.page = parent
def interceptRequest(self, info):
if info.requestUrl().toString().startswith('http://down.51en.com:88'):
self.targetUrl = info.requestUrl().toString()
print('----------------------------------------------', self.targetUrl)
qApp.quit()
# self.page.load(QUrl(''))
def targetUrlGetter(url=None):
app = QApplication(sys.argv)
page = QWebEnginePage()
globalSettings = page.settings().globalSettings()
globalSettings.setAttribute(
QWebEngineSettings.PluginsEnabled, True)
globalSettings.setAttribute(
QWebEngineSettings.AutoLoadImages, False)
profile = page.profile()
webEngineUrlRequestInterceptor = WebEngineUrlRequestInterceptor(page)
profile.setRequestInterceptor(webEngineUrlRequestInterceptor)
page.load(QUrl(url))
# view = QWebEngineView()
# view.setPage(page)
# view.show()
app.exec_()
return webEngineUrlRequestInterceptor.targetUrl
url = "http://www.51en.com/news/sci/everything-there-is-20160513.html"
# url = "http://www.51en.com/news/sci/obese-dad-s-sperm-may-influence-offsprin.html"
# url = "http://www.51en.com/news/sci/mars-surface-glass-could-hold-ancient-fo.html"
targetUrl = targetUrlGetter(url)
print(targetUrl)
You should always initialize QApplication at the beginning of the program, and always call the QApplication::exec function at the end of the program.
Another thing is that QWebEngineUrlRequestInterceptor.interceptRequest is a callback function which is called asynchronously. Since info.requestUrl().toString() is called inside the callback function, there is no way to return the result it synchronously.
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtWebEngineCore import *
from PyQt5.QtCore import *
class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
def __init__(self, parent=None):
super().__init__(parent)
self.page = parent
def interceptRequest(self, info):
if info.requestUrl().toString().startswith('http://down.51en.com:88'):
self.targetUrl = info.requestUrl().toString()
print('----------------------------------------------', self.targetUrl)
# Don't do thatDo you really want to exit the whole program?
# qApp.quit()
# Do something here, rather than return it.
# It must be run asynchronously
# self.page.load(QUrl(''))
def targetUrlGetter(url=None):
page = QWebEnginePage()
globalSettings = page.settings().globalSettings()
globalSettings.setAttribute(
QWebEngineSettings.PluginsEnabled, True)
globalSettings.setAttribute(
QWebEngineSettings.AutoLoadImages, False)
profile = page.profile()
webEngineUrlRequestInterceptor = WebEngineUrlRequestInterceptor(page)
profile.setRequestInterceptor(webEngineUrlRequestInterceptor)
page.load(QUrl(url))
# view = QWebEngineView()
# view.setPage(page)
# view.show()
# Don't return this. It cannot be called synchronously. It must be called asynchronously.
# return webEngineUrlRequestInterceptor.targetUrl
app = QApplication(sys.argv) # always initialize QApplication at the beginning of the program
url = "http://www.51en.com/news/sci/everything-there-is-20160513.html"
# url = "http://www.51en.com/news/sci/obese-dad-s-sperm-may-influence-offsprin.html"
# url = "http://www.51en.com/news/sci/mars-surface-glass-could-hold-ancient-fo.html"
targetUrl = targetUrlGetter(url)
print(targetUrl)
app.exec_() # always call the QApplication::exec at the end of the program
Related
I have an application where one of its functions is to use pytube to download YouTube videos. Everything works perfectly except for updating the QProgressBar with the download progress. Please see below code:
import pytube
import PyQt5.QtWidgets as QtWidgets
import PyQt5.QtCore as QtCore
class Worker(QtCore.QObject):
finished = QtCore.pyqtSignal()
progress = QtCore.pyqtSignal(str, int, int)
def __init__(self, url, save_path, fname):
super(Worker, self).__init__()
self.url = url
self.save_path = save_path
self.fname = fname
self.perc_dl = 0
self.download_video()
def run(self):
if self.perc_dl < 100:
self.progress.emit('Downloading: {}%'.format(str(self.perc_dl)), int(self.perc_dl), 100)
print(self.perc_dl)
else:
self.progress.emit('Done!', 100, 100)
self.finished.emit()
def download_video(self):
yt = pytube.YouTube(self.url, on_progress_callback=self.progress_function)
stream = yt.streams.filter(progressive=True, file_extension='mp4').get_highest_resolution()
stream.download(output_path=self.save_path, filename=self.fname)
def progress_function(self, stream, chunk, bytes_remaining):
curr = stream.filesize - bytes_remaining
per_downloaded = round((curr / stream.filesize) * 100, 1)
self.perc_dl = per_downloaded
self.run()
class DownloadFromYT(QtWidgets.QDialog):
def __init__(self, url, save_path, fname):
super(DownloadFromYT, self).__init__()
self.url = url
self.save_path = save_path
self.fname = fname
self.vLayoutMaster = QtWidgets.QVBoxLayout()
self.hLayout = QtWidgets.QHBoxLayout()
self.hLayout.setAlignment(QtCore.Qt.AlignRight)
self.label = QtWidgets.QLabel()
self.label.setText('Downloading video')
self.pBar = QtWidgets.QProgressBar()
self.pBar.setInvertedAppearance(True)
self.pBar.setTextVisible(True)
self.pBar.setFixedWidth(200)
self.pBar.setAlignment(QtCore.Qt.AlignCenter)
self.pBar.setMaximum(100)
self.pBar.setFormat('Downloading: ')
self.noButton = QtWidgets.QPushButton('No')
self.noButton.setFixedWidth(50)
self.noButton.hide()
self.yesButton = QtWidgets.QPushButton('Yes')
self.yesButton.setFixedWidth(50)
self.yesButton.hide()
self.vLayoutMaster.addWidget(self.label)
self.vLayoutMaster.addSpacing(10)
self.vLayoutMaster.addWidget(self.pBar)
self.vLayoutMaster.addSpacing(20)
self.hLayout.addWidget(self.noButton)
self.hLayout.addWidget(self.yesButton)
self.vLayoutMaster.addLayout(self.hLayout)
# Signals / slots
self.noButton.clicked.connect(self.reject)
self.yesButton.clicked.connect(self.accept)
# Widget
self.setLayout(self.vLayoutMaster)
self.setWindowTitle('Downloading')
self.setFixedSize(250, 100)
self.show()
# Init download
self.run_thread(url, save_path, fname)
def run_thread(self, url, save_path, fname):
self.thrd = QtCore.QThread()
self.worker = Worker(url, save_path, fname)
self.worker.moveToThread(self.thrd)
self.thrd.start()
self.thrd.started.connect(self.worker.run)
self.worker.finished.connect(self.thrd.quit)
self.worker.finished.connect(self.worker.deleteLater)
self.worker.progress.connect(self.show_progress)
self.thrd.finished.connect(self.thrd.deleteLater)
def show_progress(self, label, n, total):
self.pBar.setFormat(label)
self.pBar.setMaximum(total)
self.pBar.setValue(n)
QtCore.QCoreApplication.processEvents()
if label == 'Done!':
self.thrd.quit()
self.noButton.show()
self.yesButton.show()
self.label.setText('Video has been downloaded. Would you like to set the chosen\n'
'file path as the "Local file" path?')
I have used this basic structure in other parts of my application to display and update a progress bar with no issues, however for some reason here, self.pBar refuses to update when the progress signal is emitted from the Worker class. As you can see, I have a print() statement in the run method to check that the code is actually entering that if block and periodically printing out the download progress to the console, which it is. The application updates when the thread has finished running, so I get the final, completely filled progress bar, but in between the start and end the progress bar does not update as expected.
Any help would be greatly appreciated!
The problem seems to be that despite all your effort to wire up all that thread-worker components correctly, you are still running self.download_video() in the main (UI) thread. And therefore it is blocking refreshing of the UI. If you want to run in in the secondary thread, you must start it in Worker.run() function and not in the Worker constructor. If you wire up all threading correctly, then you should not need to call processEvents() at all to refresh UI.
If you are unsure about the thread in which the download function runs, print the thread ID in your print function and compare it to thread id of the main UI thread. Have a look at https://doc.qt.io/qt-5/qthread.html#currentThread
I tried following this answer: How to use PyQT5 to convert multiple HTML docs to PDF in one loop
I modified it to convert all html files found in a local folder. For example htmls is a list of html files to be converted: [Q:\Ray\test1.html, Q:\Ray\prac2.html]
This is the code. However, when I try to run it, Python just freezes and I have to stop the run.
import os
import glob
from PyQt5 import QtWidgets, QtWebEngineWidgets
class PdfPage(QtWebEngineWidgets.QWebEnginePage):
def __init__(self):
super().__init__()
self._htmls = []
self._current_path = ""
self.setZoomFactor(1)
self.loadFinished.connect(self._handleLoadFinished)
self.pdfPrintingFinished.connect(self._handlePrintingFinished)
def convert(self, htmls):
self._htmls = iter(zip(htmls))
self._fetchNext()
def _fetchNext(self):
try:
self._current_path = next(self._htmls)
except StopIteration:
return False
def _handleLoadFinished(self, ok):
if ok:
self.printToPdf(self._current_path)
def _handlePrintingFinished(self, filePath, success):
print("finished:", filePath, success)
if not self._fetchNext():
QtWidgets.QApplication.quit()
if __name__ == "__main__":
current_dir = os.path.dirname(os.path.realpath(__file__))
folder= current_dir+ '\\*.HTML'
htmls= glob.glob(folder)
app = QtWidgets.QApplication([])
page = PdfPage()
page.convert(htmls)
app.exec_()
print("finished")
It seems that the OP has not understood the logic of my previous solution which is:
Get the resource, in this case files,
Load it on the page,
When the load is finished then print the content of the page,
When the printing is finished then execute step 1 with the next resource.
In this it does not perform step 2, on the other hand it is recommended that the path of the pdf has a name other than the html
import os
import glob
from PyQt5.QtCore import QUrl
from PyQt5 import QtWidgets, QtWebEngineWidgets
class PdfPage(QtWebEngineWidgets.QWebEnginePage):
def __init__(self):
super().__init__()
self._htmls = []
self._current_path = ""
self.setZoomFactor(1)
self.loadFinished.connect(self._handleLoadFinished)
self.pdfPrintingFinished.connect(self._handlePrintingFinished)
def convert(self, htmls):
self._htmls = iter(htmls)
self._fetchNext()
def _fetchNext(self):
try:
self._current_path = next(self._htmls)
except StopIteration:
return False
else:
self.load(QUrl.fromLocalFile(self._current_path))
return True
def _handleLoadFinished(self, ok):
if ok:
self.printToPdf(self._current_path + ".pdf")
def _handlePrintingFinished(self, filePath, success):
print("finished:", filePath, success)
if not self._fetchNext():
QtWidgets.QApplication.quit()
if __name__ == "__main__":
current_dir = os.path.dirname(os.path.realpath(__file__))
folder= current_dir+ '\\*.HTML'
htmls = glob.glob(folder)
print(htmls)
if htmls:
app = QtWidgets.QApplication([])
page = PdfPage()
page.convert(htmls)
app.exec_()
print("finished")
This is a repost of my previous post which I deleted. In the first post I asked if someone knows a way of creating bookmarks with PyQT5, however, originally, I did not post what issues I am having now, with my way. I have 3 toolbars, in my web browser.
For additional buttons as - exit, minimize, maximize and etc.
For navigation in the web.
Bookmarks all are created with the instance of QToolBar().
Bookmarks toolbar code
self.bookmark_bar = QToolBar('Bookmark')
self.bookmark_bar.setIconSize(QSize(12, 12))
self.bookmark_bar.setMovable(False)
self.addToolBar(self.bookmark_bar)
After the tool bars are created the buttons are added, as there is a lot of code there I will show just the final result as a screenshot and the last few lines of code in init function.
The last few lines of code:
self.add_new_tab(QUrl('http://www.google.com'), 'Home Page')
self.bookmarks_load()
self.show()
self.setWindowTitle('Tempo')
Everything is fine with the Web Browser itself, as everything is working except the bookmarks. The line of code 'bookmarks_load()' load the bookmarks from a .txt file. As for now in the .txt document the bookmark is youtube.com (does not matter which link is used). The bookmarks functioncs:
Add a website to a bookmark.txt
def Bookmark(self):
try:
qurl = QUrl(self.urlbar.text())
print('Here we are using the QUrl toString method: %s ---> Type: %s' % (qurl.toString(), type(qurl)))
url = qurl.toString()
print('Here we are storing the new string to a new variable: %s ---> Type: %s' % (url, type(url)))
b = open(os.path.join('bookmarks', 'bookmarks.txt'), "wb")
self.bookmarks_write = pickle.dump(url, b)
b.close()
except:
print("Crash - Bookmarks not stored")
self.bookmark_btn.setText("★")
Load bookmarks from the document file.
def bookmarks_load(self):
try:
bookmarks_open = open(os.path.join('bookmarks', 'bookmarks.txt'), 'rb')
self.bookmarks_write = pickle.load(bookmarks_open)
bookmarks_open.close()
self.create_bookmarks()
except:
bookmarks_open = open(os.path.join('bookmarks', 'bookmarks.txt'), 'wb')
bookmarks = 'http://www.stackoverflow.com'
self.bookmarks_write = pickle.dump(bookmarks, bookmarks_open)
bookmarks_open.close()
self.create_bookmarks()
print('Crash - Did not load bookmarks')
Create the bookmarks 'button', when pressed open a new tab with that website.
def create_bookmarks(self):
bookmark_list = []
try:
for book in self.bookmarks_write.split():
print(book)
bookmark_list.append(book)
print(bookmark_list)
except:
print("Something went wrong with the list")
try:
button = QAction(QIcon(os.path.join('images', 'tab_icon.PNG')), 'Open bookmark', self)
button.triggered.connect(self.add_new_tab(QUrl(bookmark_list[0]), 'New'))
self.bookmark_bar.addAction(button)
except:
print('Button is causing the error')
Now this is the part which I start having issues. If I remove the - triggered.connect line and I do not add any functionality to that 'button' everything launches and works, without any errors. It stores and can load the bookmarks. However, when that line is added, it crashes and the button is not created(The app does not exit as there is an except statement which catches the error - which pyqt does not show what error it is.). This is the add_new_tab() function:
def add_new_tab(self, qurl=None, label='Blank'):
if qurl is None:
qurl = QUrl('')
web_browser = QWebEngineView()
web_browser.setUrl(qurl)
web_browser.adjustSize()
index = self.tabs.addTab(web_browser, label)
self.tabs.setCurrentIndex(index)
web_browser.urlChanged.connect(lambda qurl, web_browser=web_browser:
self.update_urlbar(qurl, web_browser))
web_browser.loadFinished.connect(lambda _, i=index, web_browser=web_browser:
self.tabs.setTabText(i, web_browser.page().title()))
Originally I open tabs by 'double clicking' on the tab bar with this function:
def tab_open_doubleclick(self, index):
if index == -1:
self.add_new_tab()
As you can see on the trigger - I do pass the link as QUrl and I do add a test label. The problem I have it somehow does not want to work and I can not find why, because Python PyQT5 does not show an error, it just closes with the return code.
Screenshots as explanation:
Link not added to a bookmarks.txt
Link added to bookmarks.txt
Pickle does dump the link in .txt
The "except" statement is run, while the triggered.connect line is not commented out.
The app continues to run, but the loaded bookmarks buttons are not there.
In the following example I show how to add the functionality of the BookMark, for it use QSettings to store the data but for this you must use setOrganizationName(), setOrganizationDomain() and setApplicationName(). Also I added the functionality of obtaining the title of the web page. The BookMarkToolBar class has the bookmarkClicked method that returns the url associated with the BookMark and the title.
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
class BookMarkToolBar(QtWidgets.QToolBar):
bookmarkClicked = QtCore.pyqtSignal(QtCore.QUrl, str)
def __init__(self, parent=None):
super(BookMarkToolBar, self).__init__(parent)
self.actionTriggered.connect(self.onActionTriggered)
self.bookmark_list = []
def setBoorkMarks(self, bookmarks):
for bookmark in bookmarks:
self.addBookMarkAction(bookmark["title"], bookmark["url"])
def addBookMarkAction(self, title, url):
bookmark = {"title": title, "url": url}
fm = QtGui.QFontMetrics(self.font())
if bookmark not in self.bookmark_list:
text = fm.elidedText(title, QtCore.Qt.ElideRight, 150)
action = self.addAction(text)
action.setData(bookmark)
self.bookmark_list.append(bookmark)
#QtCore.pyqtSlot(QtWidgets.QAction)
def onActionTriggered(self, action):
bookmark = action.data()
self.bookmarkClicked.emit(bookmark["url"], bookmark["title"])
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.defaultUrl = QtCore.QUrl()
self.tabs = QtWidgets.QTabWidget()
self.tabs.setTabsClosable(True)
self.setCentralWidget(self.tabs)
self.urlLe = QtWidgets.QLineEdit()
self.urlLe.returnPressed.connect(self.onReturnPressed)
self.favoriteButton = QtWidgets.QToolButton()
self.favoriteButton.setIcon(QtGui.QIcon("images/star.png"))
self.favoriteButton.clicked.connect(self.addFavoriteClicked)
toolbar = self.addToolBar("")
toolbar.addWidget(self.urlLe)
toolbar.addWidget(self.favoriteButton)
self.addToolBarBreak()
self.bookmarkToolbar = BookMarkToolBar()
self.bookmarkToolbar.bookmarkClicked.connect(self.add_new_tab)
self.addToolBar(self.bookmarkToolbar)
self.readSettings()
def onReturnPressed(self):
self.tabs.currentWidget().setUrl(QtCore.QUrl.fromUserInput(self.urlLe.text()))
def addFavoriteClicked(self):
loop = QtCore.QEventLoop()
def callback(resp):
setattr(self, "title", resp)
loop.quit()
web_browser = self.tabs.currentWidget()
web_browser.page().runJavaScript("(function() { return document.title;})();", callback)
url = web_browser.url()
loop.exec_()
self.bookmarkToolbar.addBookMarkAction(getattr(self, "title"), url)
def add_new_tab(self, qurl=QtCore.QUrl(), label='Blank'):
web_browser = QtWebEngineWidgets.QWebEngineView()
web_browser.setUrl(qurl)
web_browser.adjustSize()
web_browser.urlChanged.connect(self.updateUlrLe)
index = self.tabs.addTab(web_browser, label)
self.tabs.setCurrentIndex(index)
self.urlLe.setText(qurl.toString())
def updateUlrLe(self, url):
self.urlLe.setText(url.toDisplayString())
def readSettings(self):
setting = QtCore.QSettings()
self.defaultUrl = setting.value("defaultUrl", QtCore.QUrl('http://www.google.com'))
self.add_new_tab(self.defaultUrl, 'Home Page')
self.bookmarkToolbar.setBoorkMarks(setting.value("bookmarks", []))
def saveSettins(self):
settings = QtCore.QSettings()
settings.setValue("defaultUrl", self.defaultUrl)
settings.setValue("bookmarks", self.bookmarkToolbar.bookmark_list)
def closeEvent(self, event):
self.saveSettins()
super(MainWindow, self).closeEvent(event)
if __name__ == '__main__':
import sys
QtCore.QCoreApplication.setOrganizationName("eyllanesc.org")
QtCore.QCoreApplication.setOrganizationDomain("www.eyllanesc.com")
QtCore.QCoreApplication.setApplicationName("MyApp")
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
I have two python files, the first one is to handle database related stuff and the second one imports that file so I can use it with PyQt.
The problem is if I want to change the label in the first file it doesn't work the application just crashes.
The reason I want the first file to be able to change the label is if an error occurs when trying to connect to the DB.
Here is a short view of my code:
First file.
from mysql.connector import (connection)
from datetime import *
from RPI1_ui import Ui_Form
'''Handling of database related stuff'''
class DatabaseUtility(Ui_Form):
def __init__(self):
#DB Connection
self.cnx = None
self.cursor = None
def mysql_connect(self):
# Database connection
try:
self.cnx = connection.MySQLConnection(user='root', password='', host='127.0.0.1', database='spicadb')
self.cursor = self.cnx.cursor()
except connection.errors.InterfaceError as e:
self.lblShowInfo.setText(str(e)) # -> Try to change label
def get_table(self):
return self.run_command("SELECT * FROM tblseal")
def get_columns(self):
return self.run_command("SHOW COLUMNS FROM tblseal")
Second file.
from PyQt5.QtWidgets import QApplication, QWidget, QDialog
from datetime import *
from bs4 import BeautifulSoup as bs
import os
import sys
import DatabaseHandling
'''Convert UI file to Python'''
os.chdir("C:\\Users\Gianni Declercq\AppData\Local\Programs\Python\Python36-32\Scripts")
os.system("pyuic5.exe H:\QtProjects\\RPI1.ui -o H:\QtProjects\\RPI1_ui.py")
from RPI1_ui import Ui_Form # import after recreation of py file
from RPI1_Sec import SecondWindow
'''Main program'''
class MainWindow(QWidget, Ui_Form):
def __init__(self):
super(MainWindow, self).__init__()
# Initialize variables
self.dbu = DatabaseHandling.DatabaseUtility()
self.spica_reference = None
self.barcode = None
self.msl = None
self.package_body = None
self.window2 = None
# Get UI elements + resize window
self.setupUi(self)
self.resize(800, 480)
# Define what should happen on button click
self.btnQuit.clicked.connect(lambda: app.exit())
self.btnInsert.clicked.connect(lambda: self.get_entry())
self.btnTable.clicked.connect(lambda: self.new_window())
# Style buttons
self.btnQuit.setStyleSheet("background-color: red")
self.btnInsert.setStyleSheet("background-color: green")
self.btnTable.setStyleSheet("background-color: orange")
def get_entry(self):
try:
self.spica_reference = self.txtReferentie.text()
self.barcode = self.txtBarcode.text()
self.msl = self.txtMsl.text()
self.package_body = float(self.txtBodyPackage.text())
except ValueError:
self.lblShowInfo.setText("Please insert the correct values")
self.lblShowInfo.setStyleSheet('color: red')
else:
self.dbu.mysql_connect()
if self.dbu.cursor and self.dbu.cnx is not None:
self.dbu.add_entry(self.spica_reference, self.barcode, self.msl, self.package_body, self.calc_floor_life)
Give a "hook function" to the DatabaseUtility when initializing.
class MainWindow(QWidget, Ui_Form):
def __init__():
def ch_lab(text):
self.lblShowInfo.setText(text)
self.dbu = DatabaseHandling.DatabaseUtility(ch_lab)
class DatabaseUtility(Ui_Form):
def __init__(cb):
self.error_warn = cb
#.. error happening
self.error_warn('error')
i have developed an application using pyQt in python and using a web browser and a table to show the headers coming with the browser request.
here is my code:-
import sys
from PyQt4.QtGui import QApplication, QTableWidget, QTableWidgetItem
from PyQt4.QtCore import QUrl
from PyQt4.QtWebKit import QWebView, QWebPage
from PyQt4.QtGui import QGridLayout, QLineEdit, QWidget, QHeaderView
from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest
class RequestsTable(QTableWidget):
header = ["url", "status", "content-type","cookies","user_agent"]
def __init__(self):
super(RequestsTable, self).__init__()
self.setColumnCount(5)
self.setHorizontalHeaderLabels(self.header)
header = self.horizontalHeader()
header.setStretchLastSection(True)
def update(self, data):
last_row = self.rowCount()
next_row = last_row + 1
self.setRowCount(next_row)
for col, dat in enumerate(data, 0):
if not dat:
continue
self.setItem(last_row, col, QTableWidgetItem(dat))
class Manager(QNetworkAccessManager):
def __init__(self, table):
QNetworkAccessManager.__init__(self)
self.finished.connect(self._finished)
self.table = table
def _finished(self, reply):
user_agent = str(reply.request().rawHeader("User-Agent"))
headers = reply.rawHeaderPairs()
headers = {str(k):str(v) for k,v in headers}
content_type = headers.get("Content-Type")
url = reply.url().toString()
status = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
status, ok = status.toInt()
cookies = headers.get("Set-Cookie")
self.table.update([url, str(status), content_type,cookies,user_agent])
if __name__ == "__main__":
app = QApplication(sys.argv)
grid = QGridLayout()
browser = QWebView()
browser.load(QUrl("http://www.indiatimes.com/"))
def on_html_available():
page = QWebPage()
page.setNetworkAccessManager(manager)
# problem is here
browser.setPage(page)
# if i dont use above line then it don't show any error but the headers don't get append in the table but if i use the above line it shows me the error segmentation fault
browser.loadFinished.connect(on_html_available)
requests_table = RequestsTable()
manager = Manager(requests_table)
grid.addWidget(browser, 3, 0)
grid.addWidget(requests_table, 4, 0)
main_frame = QWidget()
main_frame.setLayout(grid)
main_frame.show()
sys.exit(app.exec_())
but the above code is showing me the error
"core dumped segmentation fault"?
what may be the problem ? please help me in resolving this issue.
Its showing this error because you are again setting the browser's page on html finished, which is wrong, to access network access manager you should first take the manager then set the manager with page and then set the browser page. let me know if you don't get this.