How can I access images from qrc.py into reportlab? - python-3.x

I have converted "image_fonts.qrc" into image_fonts_rc.py file. It has one image named as "image.png"
How can I use an image into reportlab PDF in Python from qrc.py file.
File image_fonts.qrc
<RCC>
<qresource prefix="image_fonts">
<file>image.png</file>
<file>logo.png</file>
</qresource>
</RCC>
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/image_fonts/logo.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
I used above the lines, but I get an error. Please find the below error.
TypeError: expected str, bytes or os.PathLike object, not QIcon
Minimal Example:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSql import *
from PyQt5 import uic
import sys
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, PageTemplate, TableStyle, Paragraph, Image, Spacer, Frame, Paragraph, Flowable
import image_fonts_rc
class UI(QMainWindow):
def __init__(self):
super(UI, self).__init__()
uic.loadUi("test_images.ui", self)
self.show()
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/image_fonts/logo.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
doc = SimpleDocTemplate("images.pdf", pagesize=A4, rightMargin=40, leftMargin=40, topMargin=20, bottomMargin=20, title ="Images")
width, height = A4
document = []
logo = icon
imgw = imgh = 80
im = (Image(logo, width=imgw, height=imgh))
document.append(im)
doc.build(document)
app = QApplication(sys.argv)
window = UI()
app.exec_()

It is not necessary to use QPixmap or QIcon but you must get the bytes from the image as in my previous answer:
from io import BytesIO
from PyQt5 import QtCore
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Image
import image_fonts_rc
def convert_qrc_to_bytesio(filename):
file = QtCore.QFile(filename)
if not file.open(QtCore.QIODevice.ReadOnly):
raise RuntimeError(file.errorString())
return
f = BytesIO(file.readAll().data())
return f
doc = SimpleDocTemplate(
"images.pdf",
pagesize=A4,
rightMargin=40,
leftMargin=40,
topMargin=20,
bottomMargin=20,
title="Images",
)
width, height = A4
document = []
logo = convert_qrc_to_bytesio(":/image_fonts/logo.png")
imgw = imgh = 80
im = Image(logo, width=imgw, height=imgh)
document.append(im)
doc.build(document)

Related

PyQt5.QIcon Is not showing any icon

I am trying to show the icon in the window bar and this is not simply working. I tried several solutions but still it doesn't work. Any solution for this code?
import os
from PyQt5.QtCore import *
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.browser = QWebEngineView()
self.browser.setUrl(QUrl('http://gmail.com'))
self.setCentralWidget(self.browser)
self.showMaximized()
self.setWindowTitle('G')
self.setWindowIcon(QIcon(os.path.join('cil.png')))
self.show()
app = QApplication(sys.argv)
window = MainWindow()
app.exec_()
Try putting the icon like this
icon = QIcon()
icon.addPixmap(QtGui.QPixmap()) #add full path or respective path to the icon image inside QtGui.QPixmap()
self.setWindowIcon(icon)

QWidgetAction doesn't show up in QMenu in tray

Actually, my question is the same as this question but the answer didn't help too much, tried the same but didn't work.
I want to make a slider works in the tray but what I got is a blank field only.
Is it possible to accomplish this in PyQt5? I tried a lot of things but couldn't find a solution. If it is not possible in PyQt5 then which else library can I use for this?
My code:
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import (
QSlider,
QHBoxLayout,
QLabel,
QApplication,
QWidgetAction,
)
from PyQt5.QtCore import Qt
def change_sound(value):
print(value)
class SliderWidgetAction(QFrame):
pass
class SliderAction(QWidgetAction):
def __init__(self, label="", parent=None):
QWidgetAction.__init__(self, parent)
self._widget = SliderWidgetAction(parent)
self._label = QLabel(label, self._widget)
self._slider = QSlider(Qt.Horizontal, self._widget)
self._slider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.value_changed = self._slider.valueChanged
def widget(self):
return self._widget
def label(self):
return self._label
def slider(self):
return self._slider
def createWidget(self, menu):
"""
This method is called by the QWidgetAction base class.
"""
actionWidget = self.widget()
actionLayout = QHBoxLayout(actionWidget)
actionLayout.setContentsMargins(0, 0, 0, 0)
actionLayout.addWidget(self.label())
actionLayout.addWidget(self.slider())
actionWidget.setLayout(actionLayout)
return actionWidget
app = QApplication([])
app.setQuitOnLastWindowClosed(False)
icon = QIcon("icon.png")
tray = QSystemTrayIcon()
tray.setIcon(icon)
tray.setVisible(True)
menu = QMenu()
action = SliderAction("Test", menu)
action.slider().setMinimum(10)
action.slider().setMaximum(100)
action.slider().setValue(90)
action.slider().valueChanged.connect(change_sound)
label_widget = QLabel("Hello World")
action.setDefaultWidget(label_widget)
menu.addAction(action)
tray.setContextMenu(menu)
app.exec_()

Multiple camera feeds not working with PyQt5 threading:

I have a data collection software that requires camera feeds from two different camera sources one is a Brio webcam & the other one is an IP webcam connected via USB tethering.
Now when I edited the code for streaming two multiple videos it was showing just one & not from the other.
The code is given below:
import sys
import cv2
#from gsp import GstreamerPlayer
import datetime
from pyfirmata import util, Arduino
from PyQt5 import QtCore, QtGui
import openpyxl
from openpyxl import load_workbook
from PyQt5.QtCore import pyqtSlot, QThread, pyqtSignal
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QLayout, QDialog, QApplication, QMainWindow, QFileDialog, QPushButton, QWidget, QLabel
from PyQt5.uic import loadUi
import xlrd
from xlutils.copy import copy
import serial
import xlsxwriter
from xlwt import Workbook
sys.setrecursionlimit(15000)
# For the camera feed
class Thread(QThread):
changePixmap = pyqtSignal(QImage)
def run(self):
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if ret:
rgbImage = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
convertToQtFormat = QImage(rgbImage.data, rgbImage.shape[1], rgbImage.shape[0], QImage.Format_RGB888)
p = convertToQtFormat.scaled(256, 181)
self.changePixmap.emit(p)
class Thread1(QThread):
changePixmap = pyqtSignal(QImage)
def run(self):
cap = cv2.VideoCapture('http://192.168.42.129:8080/video')
while True:
ret, frame = cap.read()
if ret:
rgbImage = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
convertToQtFormat = QImage(
rgbImage.data, rgbImage.shape[1], rgbImage.shape[0], QImage.Format_RGB888)
p1 = convertToQtFormat.scaled(111, 181)
self.changePixmap.emit(p1)
The calling functions in the main are as follows:
#pyqtSlot(QImage)
def setImage(self, image):
self.webcam.setPixmap(QPixmap.fromImage(image))
#pyqtSlot(QImage)
def setImage1(self, image):
self.webcam_2.setPixmap(QPixmap.fromImage(image))
def initUI(self):
th = Thread(self)
th1 = Thread1(self)
th1.changePixmap1.connect(self.setImage1)
th.changePixmap.connect(self.setImage)
th.start()
I am new to python programming can anyone tell me what I am doing wrong here? I tried the other approach of doing the streaming in a function & setting streams up but this was not a conventional approach as my application kept crashing due to the while loop*( I guess)*.
If I use one source at a time it works but I can't seem to get them working at a time.
I got it worked around as I wasn't adding
thread.start()
function before.

Reading frames from a folder and display in QGraphicsView in pyqt4

I am trying to read frame for a folder and display in QGraphics view.
import os
import PyQt4
from PyQt4 import QtCore, QtGui
dir = "frames"
for file in os.listdir(dir):
grview = QtGui.QGraphicsView()
scene = QtGui.QGraphicsScene()
#pixmap = QtGui.QPixmap(os.path.join(dir, file))
pixmap = QtGui.QPixmap(file)
item = QtGui.QGraphicsPixmapItem(pixmap)
self.scene.addItem(item)
grview.setScene()
grview.show()
#self.scene.update()
The folder named "frames" contains jpg files and is in the same folder as the code. But still I am not able to read the frames.
I have also tried general display without graphicsview to check if it works using the code below but it too doesn't work.
import cv2
import os
import PyQt4
from PyQt4 import QtGui,QtCore
import matplotlib.pyplot as plt
from PIL import Image
def load_images_from_folder(folder):
images = []
for filename in os.listdir(folder):
img = cv2.imread(os.path.join(folder,filename))
if img is not None:
images.append(img)
return images
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
img = load_images_from_folder('/frames')
image = Image.open(img)
image.show()
I am not able to understand what am I missing. I want to display the images sequentially in QGraphicsView resembling a video and in some particular frame I have to select the object of interest by draw a rectangle around it which has to hold in the subsequent frames as well. Is the task i am attempting possible? if yes any help is appreciated
Sorry, but I have PyQt5.
Try it:
import os
import sys
from PyQt5 import Qt
#from PyQt4 import QtCore, QtGui
class MainWindow(Qt.QMainWindow):
def __init__(self, parent=None):
Qt.QMainWindow.__init__(self, parent)
self.scene = Qt.QGraphicsScene()
self.grview = Qt.QGraphicsView(self.scene)
self.setCentralWidget(self.grview)
dir = "frames"
self.listFiles = os.listdir(dir)
self.timer = Qt.QTimer(self)
self.n = 0
self.timer.timeout.connect(self.on_timeout)
self.timer.start(1000)
self.setGeometry(700, 150, 300, 300)
self.show()
def on_timeout(self):
if self.n < len(self.listFiles):
self.scene.clear()
file = self.listFiles[self.n]
pixmap = Qt.QPixmap("frames\{}".format(file)) # !!! "frames\{}"
item = Qt.QGraphicsPixmapItem(pixmap)
self.scene.addItem(item)
self.grview.setScene(self.scene) # !!! (self.scene)
self.n += 1
else:
self.timer.stop()
app = Qt.QApplication(sys.argv)
GUI = MainWindow()
sys.exit(app.exec_())

mplot3d Dynamic Update with PyQt Designer

I'm trying to create a simple GUI that has an embedded mplot3d widget for viewing STL files. I'm currently using PyQt4 with Qt Designer for creating the layout and python 3.6.2. I've used this post as a starting point and I have been able to successfully implement a custom mplot3d widget. However, I would like to be able to dynamically update the mplot3d widget (eg. Click a button to load a new stl file and update the figure/widget). I know this is possible for 2D matplotlib figures using
manager = matplotlib.get_current_fig_manager()
manager.canvas.draw()
to update a regular matplotlib figure. But is this possible for an embedded matplotlib widget? Or a mplot3d custom widget?
Should I write I new method in the QtMplCanvas(FigureCanvas) class? I can't seem to figure out from the
FigureCanvasQTAgg
docs how to update a widget from matplotlibs backend. My code is somewhat long but I'll try to include the relevant bits:
from PyQt4 import QtCore, QtGui
import os
import sys
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4 import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
from mpl_toolkits.mplot3d import Axes3D
from stl import mesh
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
plt.switch_backend('Qt4Agg')
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(1007, 607)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.gridLayout = QtGui.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.line = QtGui.QFrame(self.centralwidget)
self.line.setFrameShape(QtGui.QFrame.VLine)
self.line.setFrameShadow(QtGui.QFrame.Sunken)
self.line.setObjectName(_fromUtf8("line"))
self.gridLayout.addWidget(self.line, 2, 1, 1, 1)
# STL VIEWER
self.graphicsView_STL = MPL_WIDGET_3D(self.centralwidget)
self.graphicsView_STL.setObjectName(_fromUtf8("graphicsView_STL"))
self.gridLayout.addWidget(self.graphicsView_STL, 2, 0, 1, 1)
# File load btn
self.import_tlbtn = QtGui.QToolButton(self.centralwidget)
self.import_tlbtn.setObjectName(_fromUtf8("import_tlbtn"))
self.gridLayout.addWidget(self.import_tlbtn, 1, 0, 1, 1)
#... More Widgets, layouts, etc.
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
self.import_tlbtn.setText(_translate("MainWindow", "...", None))
self.label_slice.setText(_translate("MainWindow", "Slice", None))
self.label_import.setText(_translate("MainWindow", "Import STL File", None))
... Code from Link
.... New file for connecting methods..
from PyQt4 import QtCore, QtGui
import UI_DED
import sys
import os
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
from stl import mesh
''' CONNECTING METHODS HERE '''
def open_file():
# Open a new file selection window
widget_f = QtGui.QWidget()
widget_f.resize(320, 240)
widget_f.setWindowTitle("Select a file")
filename = QtGui.QFileDialog.getOpenFileName(widget_f, 'Open File', '/')
if filename == '':
pass
else:
your_mesh = mesh.Mesh.from_file(filename)
stl_update(your_mesh)
# Some sort of method for updating the widget
def stl_update():
pass
# Some method for updating canvas....
if __name__ == "__main__":
plt.switch_backend('Qt4Agg')
# Set window from UI_DED
app = QtGui.QApplication(sys.argv)
MainWindow = UI_DED.QtGui.QMainWindow()
ui = UI_DED.Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
# Connect widgets here
# Import STL File
ui.import_tlbtn.clicked.connect(open_file)
# Exit
sys.exit(app.exec_())

Resources