Pdfjs print button does not work with PyQt5 - python

Straight to issue, when pdf loads with pdfjs into pyqt5, seems print button does not work correctly, also the same for download button.
How could this bug be fixed?
The code:
import sys
from PyQt5 import QtCore, QtWidgets, QtGui, QtWebEngineWidgets
PDFJS = 'file:///pdfjs/web/viewer.html'
PDF = 'file:///file0.pdf'
class PdfReport(QtWebEngineWidgets.QWebEngineView):
def __init__(self, parent=None):
super(PdfReport, self).__init__(parent)
self.load(QtCore.QUrl.fromUserInput('%s?file=%s' % (PDFJS, PDF)))
def sizeHint(self):
return QtCore.QSize(640, 480)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
im = PdfReport()
im.show()
sys.exit(app.exec_())
Display:
Any idea how to fix that?

The print task is not enabled in Qt WebEngine so the fault is displayed (I'm still trying to get the data). But in the case of the download button of the PDF it is possible and for this you must use the downloadRequested signal of the QWebEngineProfile:
import os
import sys
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
PDFJS = QtCore.QUrl.fromLocalFile(
os.path.join(CURRENT_DIR, "pdfjs/web/viewer.html")
).toString()
class PdfReport(QtWebEngineWidgets.QWebEngineView):
def __init__(self, parent=None):
super(PdfReport, self).__init__(parent)
QtWebEngineWidgets.QWebEngineProfile.defaultProfile().downloadRequested.connect(
self.on_downloadRequested
)
def load_pdf(self, filename):
url = QtCore.QUrl.fromLocalFile(filename).toString()
self.load(QtCore.QUrl.fromUserInput("%s?file=%s" % (PDFJS, url)))
def sizeHint(self):
return QtCore.QSize(640, 480)
#QtCore.pyqtSlot(QtWebEngineWidgets.QWebEngineDownloadItem)
def on_downloadRequested(self, download):
path, _ = QtWidgets.QFileDialog.getSaveFileName(
self, "Save File", "sample.pdf", "*.pdf"
)
if path:
download.setPath(path)
download.accept()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = PdfReport()
path = os.path.join(CURRENT_DIR, "file0.pdf")
w.load_pdf(path)
w.show()
sys.exit(app.exec_())

That's not a PyQt5 button, that is a button from your web view. It may not work because of your webView object or because the web part of your code lacks functionality for the button.

Related

mousePressEvent not functioning for QLabel

I read a lot of tutorials on how to get coordinates of the clicking position on an image in QLabel ("label_2" in the code below defined in "form.ui" by Qt Creator). Most of them refer to using mousePressEvent method. However, after implementing the method, it does not function when I click a point on the imported image. It seems that mousePressEvent is never called by anything. Wondering what is going wrong in it. Is there any trivial or non-trivial thing missed?
import sys
import os
from PySide2.QtWidgets import QApplication, QWidget
from PySide2.QtCore import QFile, Qt
from PySide2.QtUiTools import QUiLoader
from PySide2.QtGui import QPixmap
class qttest(QWidget):
def __init__(self):
super(qttest, self).__init__()
self.load_ui()
self.showImage()
def load_ui(self):
loader = QUiLoader()
path = os.path.join(os.path.dirname(__file__), "form.ui")
ui_file = QFile(path)
ui_file.open(QFile.ReadOnly)
self.ui = loader.load(ui_file, self)
ui_file.close()
def showImage(self,file='img.jpg'):
pixmap = QPixmap(file)
pixmap1 = pixmap.scaled(200, 200, Qt.KeepAspectRatio)
self.ui.label_2.setPixmap(pixmap1)
self.ui.label_2.mousePressEvent = self.getPos
def getPos(self,event):
x = event.pos().x()
y = event.pos().y()
print(x,y)
if __name__ == "__main__":
app = QApplication([])
widget = qttest()
widget.show()
sys.exit(app.exec_())
Figured out the problem by ourselves. self.ui = loader.load(ui_file, self) in the code is not a recommended way to take all items in "form.ui" into consideration. By using uic imported from PyQt5 package, this could be solved.

PyQt5 add eventFilter outside of pyuic generated code

I'm a new Qt user here.
I've got a project where I'm to use a pyuic generated .py file but I don't have access to it.
I'm also supposed to be installing event filters on some of the objects. Is it possible to use object.installEventFilter() outside the generated .py file?
main_window.py
class Ui_MainWindow(QtWidgets.QMainWindow):
self.titleLabel = QtWidgets.QLabel(MainWindow)
Frontend.py
from PyQt5 import QtCore, QtGui, QtWidgets
from main_window import Ui_MainWindow
class Session (object):
def __init__(self):
self.mainUI = None
def eventFilter(self, source, event):
eventReturn = False
if(event.type() == QtCore.QEvent.MouseButtonDblClick and
source is self.lblTitle):
eventReturn = self._labelTitle(source, event)
return eventReturn
def _labelTitle(self, widget, event):
retVal = True
print("works, Title")
def GUIcontroller():
import sys
app = QtWidgets.QApplication(sys.argv)
thisSession = Session()
MainWindow = QtWidgets.QMainWindow()
thisSession.mainUI = Ui_MainWindow()
thisSession.mainUI.setupUi(MainWindow)
thisSession.mainUI.titleLabel.installEventFilter(???)
MainWindow.show()
sys.exit(app.exec_())
if __name__ == "__main__":
GUIcontroller()
The event filters only work in the QObjects, and in your code you use object that will not work, considering the above a possible solution is:
from PyQt5 import QtCore, QtGui, QtWidgets
from main_window import Ui_MainWindow
class Session(QtCore.QObject):
def __init__(self, ui):
super().__init__(ui)
self._ui = ui
self.ui.installEventFilter(self)
#property
def ui(self):
return self._ui
def eventFilter(self, source, event):
if event.type() == QtCore.QEvent.MouseButtonDblClick and source is self.ui:
print("double clicked")
return super().eventFilter(source, event)
def GUIcontroller():
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
mainUI = Ui_MainWindow()
mainUI.setupUi(MainWindow)
thisSession = Session(mainUI.titleLabel)
MainWindow.show()
sys.exit(app.exec_())
if __name__ == "__main__":
GUIcontroller()

QFileDialog always opens behind main window

I'm trying to open a file in my PySide2 application, but the file dialog always opens below the main window and appears as another application in the launcher. The application's name is "Portal".
I see other answers where the solution is to pass the main window as the first parameter to getOpenFileName(), but that doesn't work for me.
Here's a simple demonstration of the problem:
import sys
from PySide2.QtWidgets import QPushButton, QFileDialog, QApplication
class DemoButton(QPushButton):
def __init__(self, text):
super().__init__(text)
self.clicked.connect(self.on_click)
def on_click(self):
file_name, _ = QFileDialog.getOpenFileName(
self,
"Open a text file.",
filter='Text file (*.txt)')
print(file_name)
def main():
app = QApplication(sys.argv)
button = DemoButton("Hello World")
button.show()
app.exec_()
sys.exit()
main()
I thought maybe the parent had to be a QMainWindow, so I tried that:
import sys
from PySide2 import QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
main_widget = QtWidgets.QWidget(self)
self.setCentralWidget(main_widget)
# layout initialize
g_layout = QtWidgets.QVBoxLayout()
layout = QtWidgets.QFormLayout()
main_widget.setLayout(g_layout)
# Add Widgets
self.exec_btn = QtWidgets.QPushButton('Execute')
self.exec_btn.clicked.connect(self.find_file)
# global layout setting
g_layout.addLayout(layout)
g_layout.addWidget(self.exec_btn)
def find_file(self):
file_name, _ = QtWidgets.QFileDialog.getOpenFileName(
self,
"Open a text file.",
filter='Text file (*.txt)')
print(file_name)
def main():
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
sys.exit()
main()
The file dialog behaved exactly the same.
I'm using PySide2 5.12.2, Python 3.6.7, and running on Ubuntu 18.04.
Thanks to ekhumoro's comment, I learned that I can tell PySide2 not to use the native file dialog.
import sys
from PySide2.QtWidgets import QPushButton, QFileDialog, QApplication
class DemoButton(QPushButton):
def __init__(self, text):
super().__init__(text)
self.clicked.connect(self.on_click)
def on_click(self):
file_name, _ = QFileDialog.getOpenFileName(
self,
"Open a text file.",
filter='Text file (*.txt)',
options=QFileDialog.DontUseNativeDialog)
print(file_name)
def main():
app = QApplication(sys.argv)
button = DemoButton("Hello World")
button.show()
app.exec_()
sys.exit()
main()
That fixes the behaviour by bringing the file dialog to the front, but I think the native file dialog looks better. Hopefully, there's another option that can make the native file dialog work properly.

How to make another window which has the same geometry (position and width, height) as the original window, to simulate that the entire page changed? [duplicate]

I'm just getting started with PyQt5. I have been trying to accomplish a seemingly very simple task but haven't been able to get enough info about it. After a fair bit of googling I have been able to get one window to close and another to launch with the other UI loaded but that's not what I want to do here.
I want to switch the UI in the same window. I am loading the UI files as global variables in my python file where I have 2 classes for each UI. When I click a particular button in one UI, I want to switch to the other UI in the same window. Below is a sample of the code:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
from PyQt5.uic import loadUiType
import os
about_company_ui, _ = loadUiType(os.path.join('frontend', 'ui', 'about_company.ui'))
intern_placement_ui, _ = loadUiType(os.path.join('frontend', 'ui', 'intern_placement.ui'))
class InternPlacement(QMainWindow, intern_placement_ui):
def __init__(self):
QMainWindow.__init__(self)
self.setupUi(self)
self.intern_pushButton.clicked.connect(self.change)
def change(self):
self.about_company = AboutCompany()
self.about_company.show()
self.close()
class AboutCompany(QMainWindow, about_company_ui):
def __init__(self):
QMainWindow.__init__(self)
self.setupUi(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = InternPlacement()
window.show()
app.exec_()
You have to use a QStackedWidget
import os
import sys
from PyQt5 import QtCore, QtGui, QtWidgets, uic
ui_folder = os.path.join("frontend", "ui")
about_company_ui, _ = uic.loadUiType(os.path.join(ui_folder, "about_company.ui"))
intern_placement_ui, _ = uic.loadUiType(os.path.join(ui_folder, "intern_placement.ui"))
class InternPlacement(QtWidgets.QMainWindow, intern_placement_ui):
def __init__(self, parent=None):
super(InternPlacement, self).__init__(parent)
self.setupUi(self)
class AboutCompany(QtWidgets.QMainWindow, about_company_ui):
def __init__(self, parent=None):
super(AboutCompany, self).__init__(parent)
self.setupUi(self)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
intern_window = InternPlacement()
about_window = AboutCompany()
w = QtWidgets.QStackedWidget()
w.addWidget(intern_window)
w.addWidget(about_window)
intern_window.intern_pushButton.clicked.connect(lambda: w.setCurrentIndex(1))
w.resize(640, 480)
w.show()
sys.exit(app.exec_())

How to change UI in same window using PyQt5?

I'm just getting started with PyQt5. I have been trying to accomplish a seemingly very simple task but haven't been able to get enough info about it. After a fair bit of googling I have been able to get one window to close and another to launch with the other UI loaded but that's not what I want to do here.
I want to switch the UI in the same window. I am loading the UI files as global variables in my python file where I have 2 classes for each UI. When I click a particular button in one UI, I want to switch to the other UI in the same window. Below is a sample of the code:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
from PyQt5.uic import loadUiType
import os
about_company_ui, _ = loadUiType(os.path.join('frontend', 'ui', 'about_company.ui'))
intern_placement_ui, _ = loadUiType(os.path.join('frontend', 'ui', 'intern_placement.ui'))
class InternPlacement(QMainWindow, intern_placement_ui):
def __init__(self):
QMainWindow.__init__(self)
self.setupUi(self)
self.intern_pushButton.clicked.connect(self.change)
def change(self):
self.about_company = AboutCompany()
self.about_company.show()
self.close()
class AboutCompany(QMainWindow, about_company_ui):
def __init__(self):
QMainWindow.__init__(self)
self.setupUi(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = InternPlacement()
window.show()
app.exec_()
You have to use a QStackedWidget
import os
import sys
from PyQt5 import QtCore, QtGui, QtWidgets, uic
ui_folder = os.path.join("frontend", "ui")
about_company_ui, _ = uic.loadUiType(os.path.join(ui_folder, "about_company.ui"))
intern_placement_ui, _ = uic.loadUiType(os.path.join(ui_folder, "intern_placement.ui"))
class InternPlacement(QtWidgets.QMainWindow, intern_placement_ui):
def __init__(self, parent=None):
super(InternPlacement, self).__init__(parent)
self.setupUi(self)
class AboutCompany(QtWidgets.QMainWindow, about_company_ui):
def __init__(self, parent=None):
super(AboutCompany, self).__init__(parent)
self.setupUi(self)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
intern_window = InternPlacement()
about_window = AboutCompany()
w = QtWidgets.QStackedWidget()
w.addWidget(intern_window)
w.addWidget(about_window)
intern_window.intern_pushButton.clicked.connect(lambda: w.setCurrentIndex(1))
w.resize(640, 480)
w.show()
sys.exit(app.exec_())

Categories

Resources