QtWebkit: loadFinished and loadProgress slots are never executed - python

Here is a basic PyQt code for Webkit I was trying out.
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
from PyQt4.QtNetwork import *
class XPrinter(QObject):
def __init__(self):
QObject.__init__(self)
def print_page_info(self, ok):
print ok
def print_load_started(self):
print 'started loading'
def print_load_percent(self, percent):
print percent
app = QApplication(sys.argv)
web = QWebView()
xprinter = XPrinter()
QObject.connect(web, SIGNAL("loadFinished()"), xprinter.print_page_info)
QObject.connect(web, SIGNAL("loadStarted()"), xprinter.print_load_started)
QObject.connect(web, SIGNAL("loadProgress()"), xprinter.print_load_percent)
web.load(QUrl("http://www.gnu.org"))
web.setWindowState(Qt.WindowMaximized)
web.show()
sys.exit(app.exec_())
I am facing the problem that the slots loadFinished and loadProgress are never executed. Please tell me where I am doing it wrong?

Try using the new style signals
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
from PyQt4.QtNetwork import *
class XPrinter(QObject):
def __init__(self):
QObject.__init__(self)
def print_page_info(self, ok):
print ok
def print_load_started(self):
print 'started loading'
def print_load_percent(self, percent):
print percent
app = QApplication(sys.argv)
web = QWebView()
xprinter = XPrinter()
web.loadFinished.connect(xprinter.print_page_info)
web.loadStarted.connect(xprinter.print_load_started)
web.loadProgress.connect(xprinter.print_load_percent)
web.load(QUrl("http://www.gnu.org"))
web.setWindowState(Qt.WindowMaximized)
web.show()
sys.exit(app.exec_())
EDIT:
Also you had the wrong signatures
QWebview
QObject.connect(web, SIGNAL("loadFinished(bool)"), xprinter.print_page_info)
QObject.connect(web, SIGNAL("loadStarted()"), xprinter.print_load_started)
QObject.connect(web, SIGNAL("loadProgress(int )"), xprinter.print_load_percent)

Related

SetText in Pyqt5

I am developing an application in pyqt5 and I ran into one problem.
There is a script that receives data, and in pyqt5 in the line "main_text.setText (str (TEXT))" I output them, and in the format "str" ​ But the script itself receives and outputs data every 0.2s, but in the line "main_text.setText (str (TEXT))" they are not updated.
Tried through the time sleep function, the app doesn't work,
what method in pyqt5 can be used to output different data to the same set text ?
My code :
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
import MetaTrader5 as mt5
import time
mt5.initialize()
ticket_info = mt5.symbol_info_tick("EURUSD")._asdict()
bid_usd = mt5.symbol_info_tick("EURUSD").bid
def applecation():
app = QApplication(sys.argv)
window = QMainWindow()
window.setWindowTitle('Test Programm')
window.setGeometry(300, 250, 350, 200)
main_text = QtWidgets.QLabel(window)
main_text.setText(str(bid_usd))
main_text.move(100,100)
main_text.adjustSize()
window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
applecation()
You are invoking the symbol_info_tick method only once so you will only get a data, if you want to get that information every T seconds then you must use a while True that is executed in a secondary thread so that it does not block the GUI and send the information through of signals.
import sys
import threading
import time
from PyQt5.QtCore import QObject, pyqtSignal
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow
import MetaTrader5 as mt5
class MetaTrader5Worker(QObject):
dataChanged = pyqtSignal(str)
def start(self):
threading.Thread(target=self._execute, daemon=True).start()
def _execute(self):
mt5.initialize()
while True:
bid_usd = mt5.symbol_info_tick("EURUSD").bid
self.dataChanged.emit(str(bid_usd))
time.sleep(0.5)
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.label = QLabel(self)
self.setWindowTitle("Test Programm")
self.setGeometry(300, 250, 350, 200)
def handle_data_changed(self, text):
self.label.setText(text)
self.label.adjustSize()
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
worker = MetaTrader5Worker()
worker.dataChanged.connect(window.handle_data_changed)
worker.start()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
You can use threading , it's easier to understand than QThreads
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow
import threading
import sys
import MetaTrader5 as mt5
import time
mt5.initialize()
ticket_info = mt5.symbol_info_tick("EURUSD")._asdict()
bid_usd = mt5.symbol_info_tick("EURUSD").bid
def applecation():
app = QApplication(sys.argv)
window = QMainWindow()
window.setWindowTitle('Test Programm')
window.setGeometry(300, 250, 350, 200)
main_text = QtWidgets.QLabel(window)
main_text.move(100,100)
main_text.adjustSize()
def update_text():
while True:
main_text.setText(str(bid_usd))
time.sleep(0.2)
t1 = threading.Thread(target = update_text())
t1.start()
window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
applecation()

How do I update my PyQt5 icon every 60 seconds?

I am new to python and I am makeing a simple appliacation where the value of bitcoin is displayed in the system tray. I am useing PyQt5.
My question is: How do I refresh the value and icon every minute. When I try it my menu wont work anymore. Is there a simple fix?
This is my code:
import sys
import time
import math
import json
from PyQt5.QtWidgets import QApplication, QSystemTrayIcon, QMenu
from PyQt5.QtGui import QIcon
from urllib.request import urlopen
from time import sleep
app = QApplication(sys.argv)
while True:
# Connecting the api
with urlopen("https://api.alternative.me/v2/ticker/1/") as response:
source = response.read()
data = json.loads(source)
price = (json.dumps(data['data']['1']['quotes']['USD']['price']))
change = (json.dumps(data['data']['1']['quotes']['USD']['percentage_change_1h']))
intPrice = float(price)
intChange = float(change)
roundPrice = round(intPrice,2)
roundStringPrice = str(roundPrice)
# Icon change
if intChange <=0.00:
trayIcon = QSystemTrayIcon(QIcon('icons/down.png'), parent=app)
else:
trayIcon = QSystemTrayIcon(QIcon('icons/up.png'), parent=app)
trayIcon.setToolTip(roundStringPrice + ' USD')
trayIcon.show()
time.sleep(5)
trayIcon.update()
menu = QMenu()
exitAction = menu.addAction('Quit app')
exitAction.triggered.connect(app.quit)
trayIcon.setContextMenu(menu)
sys.exit(app.exec_())
Don't use while True, urlopen or time.sleep as they block the eventloop, instead use a QTimer with QNetworkAccessManager:
import os.path
import json
from functools import cached_property
from PyQt5.QtCore import pyqtSignal, QObject, QTimer, QUrl
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QMenu, QMessageBox, QSystemTrayIcon
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
class ApiManager(QObject):
infoChanged = pyqtSignal(float, float)
def __init__(self, parent=None):
super().__init__(parent)
self.manager.finished.connect(self.handle_finished)
#cached_property
def manager(self):
return QNetworkAccessManager()
def start_request(self):
url = QUrl("https://api.alternative.me/v2/ticker/1/")
qrequest = QNetworkRequest(url)
self.manager.get(qrequest)
def handle_finished(self, reply):
if reply.error() != QNetworkReply.NoError:
print(f"code: {reply.error()} message: {reply.errorString()}")
else:
print("successful")
source = reply.readAll().data()
data = json.loads(source)
r = data["data"]["1"]["quotes"]["USD"]
price = r["price"]
change = r["percentage_change_1h"]
self.infoChanged.emit(price, change)
class SystemTrayIcon(QSystemTrayIcon):
def __init__(self, parent=None):
super().__init__(parent)
self.setIcon(QIcon(self.get_resource("icons/up.png")))
self.menu = QMenu()
exitAction = self.menu.addAction("Quit app")
exitAction.triggered.connect(QApplication.quit)
self.setContextMenu(self.menu)
self.manager = ApiManager()
self.manager.infoChanged.connect(self.handle_info_changed)
timer = QTimer(self, timeout=self.manager.start_request, interval=60 * 1000)
timer.start()
self.manager.start_request()
def get_resource(self, path):
return os.path.join(CURRENT_DIR, path)
def handle_info_changed(self, price, change):
icon = (
QIcon(self.get_resource("icons/down.png"))
if change < 0
else QIcon(self.get_resource("icons/up.png"))
)
self.setIcon(icon)
self.setToolTip(f"{price:.2f} USD")
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
if not QSystemTrayIcon.isSystemTrayAvailable():
QMessageBox.critical(
None, "Systray", "I couldn't detect any system tray on this system."
)
sys.exit(1)
QApplication.setQuitOnLastWindowClosed(False)
trayIcon = SystemTrayIcon(parent=app)
trayIcon.show()
sys.exit(app.exec_())

How to get data from one file to another file in a Tablewidget

I am new to python and Im working on a personal project to mannage my workshop i have a QDialog.ui to with a tablewidget that i want to fill with a SQL Server query in a file called DBtest.py, and I have my main Index_test.py file but cant communicate both of the can some one give me a hint?
main index_test.py
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
import DBtest
from PyQt5.uic import loadUiType
import pyodbc
ui,_ = loadUiType('Simple.ui')
class MainApp(QDialog , ui):
def __init__(self):
QDialog.__init__(self) #sacar en nombre del UI
self.setupUi(self) #muestra el ui en esta aplicacion
def Show_Table():
DBtest.Show_Clientes(data)
def main():
app = QApplication(sys.argv)
window = MainApp()
window.show()
app.exec_()
if __name__ == '__main__':
main()
DBtest.py
class ShowData():
def Show_Clientes(self):
self.db = pyodbc.connect('Driver={SQL Server};'
'Server=PC-ROMO-INGENIE\MTDB;'
'Database=dbsistema;'
'Trusted_Connection=yes;')
self.cursor = self.db.cursor()
self.cursor.execute ('''SELECT nombre, RFC, descripcion, direccion, telefono, email FROM cliente Where tipo_cliente = 'Cliente' ''')
data = self.cursor.fetchall()
if data :
self.tableWidget.setRowCount(0)
self.tableWidget.insertRow(0)
for row , form in enumerate(data):
for column , item in enumerate(form):
self.tableWidget.setItem(row , column , QTableWidgetItem(str(item)))
column += 1
row_position = self.tableWidget.rowCount()
self.tableWidget.insertRow(row_position)
solved it, I had to import DBtest.py into the index.py and run the
`from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
import DBtest #import this py file
from PyQt5.uic import loadUiType
import pyodbc
ui,_ = loadUiType('Simple.ui')
class MainApp(QDialog , ui):
def __init__(self):
QDialog.__init__(self)
self.setupUi(self)
Show_dbclass = DBtest.Show_Clientes(self)#here
def Show_Table(self):
self.Show_dbclass()
def main():
app = QApplication(sys.argv)
window = MainApp()
window.show()
app.exec_()
if __name__ == '__main__':
main()`

How to set a QWebEngineProfile to a QWebEngineView

I want to set different QWebEngineProfiles to different QWebEngineViews meaning each view will have its own cookie store. I cant find any documentation on it therefore all help would be greatly appreciated.
Any suggestion of another method of setting independent cookie stores to independent webviews will also help. Cheers.
Code is below (connecting the signal did not format properly here but rest assured it is correct in the real code):
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtWebEngineWidgets import *
import sys
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args,**kwargs)
self.browser={}
self.cookiestore={}
self.page={}
No = input("No: ")
for i in range(int(No)):
self.browser[str(i)] = QWebEngineView()
storagename = str(i)
self.cookiestore[str(i)] = QWebEngineProfile(storagename, self.browser[str(i)])
self.page[str(i)] = QWebEnginePage(self.cookiestore[str(i)], self.browser[str(i)])
self.browser[str(i)].setPage(self.page[str(i)])
self.browser[str(i)].load(QUrl("https://www.google.com"))
self.browser[str(i)].loadFinished.connect(lambda:self._loaded(str(i)))
def _loaded(self, No):
self.browser[No].page().toHtml(self._callable)
def _callable(self, data):
self.html = data
if "" in self.html:
print("Done")
else:
print("wait")
app = QApplication(sys.argv)
window = MainWindow()
app.exec_()
If you want to establish a QWebEngineProfile to a QWebEngineView you must do it through a QWebEnginePage as I show below:
webview = QWebEngineView()
profile = QWebEngineProfile("somestorage", webview)
webpage = QWebEnginePage(profile, webview)
webview.setPage(webpage)
Example:
from PyQt5.QtCore import QUrl
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineProfile, QWebEnginePage
from PyQt5.QtWidgets import QApplication
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
views = []
for i in range(5):
webview = QWebEngineView()
profile = QWebEngineProfile(f"storage-{i}", webview)
webpage = QWebEnginePage(profile, webview)
webview.setPage(webpage)
webview.load(QUrl("https://stackoverflow.com/questions/48142341/how-to-set-a-qwebengineprofile-to-a-qwebengineview"))
webview.show()
views.append(webview)
sys.exit(app.exec_())

PyQT QTabWidget currentChanged

I'm trying to build a little app that loads several webpages in an QTabWidget. This already works well. Now I want the tabs / QWebViews to be reloaded when the current Tab is changed.
I think that there is a problem connection the function "onChange" to the currentChanged-Event.
This is my Code:
#!/usr/bin/env python
import sys, os
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
from PyQt4.QtNetwork import *
from PyQt4 import QtCore, QtGui, QtWebKit
from PyQt4.QtWebKit import QWebView
class BaseWindow(QtGui.QMainWindow):
def __init__(self, parent = None):
QtGui.QMainWindow.__init__(self, parent)
self.centralWidget = QtGui.QWidget()
self.resize(800, 500)
self.setWindowTitle('Test')
self.tabs = QTabWidget()
#self.tabs.connect(self.tabs,SIGNAL("currentChanged(int)"),self,SLOT("onChange(int)")) #tabs,SLOT("tabChangedSlot(int)")
#self.tabs.currentChanged.connect(self.onChange)
self.webview = QWebView()
self.webview.load(QUrl("http://gmx.de"))
self.webview2 = QWebView()
self.webview2.load(QUrl("http://web.de"))
centralLayout = QtGui.QVBoxLayout()
centralLayout.addWidget(self.tabs, 1)
self.tabs.addTab(self.webview, "gmx")
self.tabs.addTab(self.webview2, "web")
self.centralWidget.setLayout(centralLayout)
self.setCentralWidget(self.centralWidget)
##pyqtSlot()
def onChange(self):
QtGui.QMessageBox.information(self,
"Tab Index Changed!",
"Current Tab Index: ");
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = BaseWindow()
window.show()
sys.exit(app.exec_())
I hope that you can help me solving my problem! Thanks a lot!
Check the changes needed on your code here:
import sys, os
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
from PyQt4.QtNetwork import *
from PyQt4 import QtCore, QtGui, QtWebKit
from PyQt4.QtWebKit import QWebView
class BaseWindow(QtGui.QMainWindow):
def __init__(self, parent = None):
QtGui.QMainWindow.__init__(self, parent)
self.centralWidget = QtGui.QWidget()
self.resize(800, 500)
self.setWindowTitle('Test')
self.tabs = QTabWidget()
self.tabs.blockSignals(True) #just for not showing the initial message
self.tabs.currentChanged.connect(self.onChange) #changed!
self.webview = QWebView()
self.webview.load(QUrl("http://gmx.de"))
self.webview2 = QWebView()
self.webview2.load(QUrl("http://web.de"))
centralLayout = QtGui.QVBoxLayout()
centralLayout.addWidget(self.tabs, 1)
self.tabs.addTab(self.webview, "gmx")
self.tabs.addTab(self.webview2, "web")
self.centralWidget.setLayout(centralLayout)
self.setCentralWidget(self.centralWidget)
self.tabs.blockSignals(False) #now listen the currentChanged signal
##pyqtSlot()
def onChange(self,i): #changed!
QtGui.QMessageBox.information(self,
"Tab Index Changed!",
"Current Tab Index: %d" % i ) #changed!
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = BaseWindow()
window.show()
sys.exit(app.exec_())

Categories