Mapping position of QLabel on an image - python

I'm trying to segment an image using Qlabels, these Qlabels are placed on an image then the segmentation will be done by pressing the segment button, I have done working on cropping function, its work but the result of the cropped images are not matched with the exact location of labels on the image.
Here is my code:
def crop(self):
i=1
image = self.UserImageLbl.pixmap()
for label in self.labels:
currentQRect = label.geometry()
#pixmap_rect = self.UserImageLbl.geometry()
tr = QtGui.QTransform()
r = tr.mapRect(currentQRect)
cropQPixmap = image.copy(r)
cropQPixmap.save('OUT '+str(i)+'.png')
i=i+1
Complete Code example:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QLabel, QWidget
from PyQt5.QtGui import QDrag, QPixmap, QPainter, QCursor
from PyQt5.QtCore import QMimeData, Qt
class DraggableLabel(QLabel):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setStyleSheet("border-color: rgb(238, 0, 0); border-width : 2.0px; border-style:inset; background: transparent;")
self.origin = None
def setLimits(self, rect):
self.limits = rect
def mousePressEvent(self, event):
if not self.origin:
# update the origin point, we'll need that later
self.origin = self.pos()
if event.button() == Qt.LeftButton:
self.mousePos = event.pos()
def mouseMoveEvent(self, event):
if event.buttons() == Qt.LeftButton:
# move the box
self.move(self.pos() + event.pos() - self.mousePos)
def mouseReleaseEvent(self, event):
if event.button() == Qt.LeftButton:
# if the box is not within the image boundaries, move it
# back to the original position
if not self.limits.contains(self.geometry()):
self.move(self.origin)
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.setEnabled(True)
Dialog.resize(1050, 800)
Dialog.setMinimumSize(QtCore.QSize(1050, 800))
Dialog.setMaximumSize(QtCore.QSize(1050, 800))
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("../.designer/backup/project pic/images icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
Dialog.setWindowIcon(icon)
Dialog.setStyleSheet("background-color: rgb(217, 217, 217);\n"
"background-color: rgb(243, 243, 243);")
self.BrowesImageButton = QtWidgets.QPushButton(Dialog)
self.BrowesImageButton.setGeometry(QtCore.QRect(820, 60, 200, 60))
self.BrowesImageButton.setMinimumSize(QtCore.QSize(200, 60))
self.BrowesImageButton.setMaximumSize(QtCore.QSize(200, 60))
font = QtGui.QFont()
font.setFamily("Microsoft YaHei UI")
font.setPointSize(11)
font.setBold(True)
font.setWeight(75)
self.BrowesImageButton.setFont(font)
self.BrowesImageButton.setStyleSheet("")
self.BrowesImageButton.setCheckable(True)
self.BrowesImageButton.setObjectName("BrowesImageButton")
self.groupBox = QtWidgets.QGroupBox(Dialog)
self.groupBox.setGeometry(QtCore.QRect(820, 170, 211, 131))
font = QtGui.QFont()
font.setFamily("Microsoft YaHei")
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.groupBox.setFont(font)
self.groupBox.setLayoutDirection(QtCore.Qt.LeftToRight)
self.groupBox.setObjectName("groupBox")
self.checkBox_Short = QtWidgets.QCheckBox(self.groupBox)
self.checkBox_Short.setGeometry(QtCore.QRect(20, 40, 141, 23))
font = QtGui.QFont()
font.setFamily("Adobe Heiti Std R")
font.setPointSize(10)
self.checkBox_Short.setFont(font)
self.checkBox_Short.setLayoutDirection(QtCore.Qt.LeftToRight)
self.checkBox_Short.setObjectName("checkBox_Short")
self.checkBox_Short.setEnabled(False)
self.checkBox_Long = QtWidgets.QCheckBox(self.groupBox)
self.checkBox_Long.setGeometry(QtCore.QRect(20, 80, 141, 23))
font = QtGui.QFont()
font.setFamily("Adobe Heiti Std R")
font.setPointSize(10)
self.checkBox_Long.setFont(font)
self.checkBox_Long.setLayoutDirection(QtCore.Qt.LeftToRight)
self.checkBox_Long.setObjectName("checkBox_Long")
self.checkBox_Long.setEnabled(False)
self.SegmentImageButton = QtWidgets.QPushButton(Dialog)
self.SegmentImageButton.setGeometry(QtCore.QRect(830, 330, 200, 60))
self.SegmentImageButton.setMinimumSize(QtCore.QSize(200, 60))
self.SegmentImageButton.setMaximumSize(QtCore.QSize(200, 60))
font = QtGui.QFont()
font.setFamily("Microsoft YaHei UI")
font.setPointSize(11)
font.setBold(True)
font.setWeight(75)
self.SegmentImageButton.setFont(font)
self.SegmentImageButton.setStyleSheet("")
self.SegmentImageButton.setCheckable(True)
self.SegmentImageButton.setObjectName("SegmentImageButton")
self.SegmentImageButton.setEnabled(False)
self.UserImageLbl = QtWidgets.QLabel(Dialog)
self.UserImageLbl.setGeometry(QtCore.QRect(40, 40, 750, 500))
self.UserImageLbl.setMinimumSize(QtCore.QSize(750, 500))
self.UserImageLbl.setMaximumSize(QtCore.QSize(750, 500))
self.UserImageLbl.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.UserImageLbl.setFrameShadow(QtWidgets.QFrame.Plain)
self.UserImageLbl.setLineWidth(1)
self.UserImageLbl.setMidLineWidth(0)
self.UserImageLbl.setText("")
self.UserImageLbl.setScaledContents(False)
self.UserImageLbl.setAlignment(QtCore.Qt.AlignCenter)
self.UserImageLbl.setObjectName("UserImageLbl")
self.buttonGroup = QtWidgets.QButtonGroup()
self.buttonGroup.addButton(self.checkBox_Short)
self.buttonGroup.addButton(self.checkBox_Long)
self.label_1 = DraggableLabel(Dialog)
self.label_2 = DraggableLabel(Dialog)
self.label_3 = DraggableLabel(Dialog)
self.label_1.move(820, 470)
self.label_2.move(900, 470)
self.label_3.move(980, 470)
self.labels = [self.label_1, self.label_2, self.label_3]
for label in self.labels:
label.hide()
label.raise_()
self.BrowesImageButton.clicked.connect(self.setImage)
self.checkBox_Long.toggled.connect(self.setBoxSizes)
self.checkBox_Short.toggled.connect(self.setBoxSizes)
self.SegmentImageButton.clicked.connect(self.crop)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Cropping"))
self.BrowesImageButton.setText(_translate("Dialog", "Select Image"))
self.groupBox.setTitle(_translate("Dialog", "Choose Type"))
self.checkBox_Short.setText(_translate("Dialog", "Short "))
self.checkBox_Long.setText(_translate("Dialog", "Long "))
self.SegmentImageButton.setText(_translate("Dialog", "Segment Image"))
def setImage(self):
fileName, _ = QtWidgets.QFileDialog.getOpenFileName(None, "Select Image", "", "Image Files (*.png *.jpg *jpeg *.bmp)") # Ask for file
if fileName: # If the user gives a file
pixmap = QtGui.QPixmap(fileName) # Setup pixmap with the provided image
pixmap = pixmap.scaled(self.UserImageLbl.width(), self.UserImageLbl.height(), QtCore.Qt.KeepAspectRatio) # Scale pixmap
self.UserImageLbl.setPixmap(pixmap) # Set the pixmap onto the label
self.UserImageLbl.setAlignment(QtCore.Qt.AlignCenter) # Align the label to center
#UserImageLbl = DropLabel()
self.checkBox_Short.setEnabled(True)
self.checkBox_Long.setEnabled(True)
def setBoxSizes(self):
if self.checkBox_Short.isChecked():
self.SegmentImageButton.setEnabled(True)
boxSize = 80
else:
boxSize = 60
self.SegmentImageButton.setEnabled(True)
for label in self.labels:
label.setFixedSize(boxSize, boxSize)
label.setLimits(self.UserImageLbl.geometry())
label.show()
def crop(self):
i=1
image = self.UserImageLbl.pixmap()
for label in self.labels:
currentQRect = label.geometry()
#pixmap_rect = self.UserImageLbl.geometry()
tr = QtGui.QTransform()
r = tr.mapRect(currentQRect)
cropQPixmap = image.copy(r)
cropQPixmap.save('OUT '+str(i)+'.png')
i=i+1
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
can someone tell me what's wrong with my code!
Thanks

First of all do not modify the code generated by Qt Designer but you must create a class that inherits from a widget and use the generated class to fill it.
On the other hand considering the above a simpler solution than to make a crop in the QPixmap is to record a section of the window.
from PyQt5 import QtCore, QtGui, QtWidgets
class DraggableLabel(QtWidgets.QLabel):
def __init__(self, parent=None):
super().__init__(parent)
self.setStyleSheet(
"border-color: rgb(238, 0, 0); border-width : 2.0px; border-style:inset; background: transparent;"
)
self.origin = QtCore.QPoint()
def setLimits(self, rect):
self.limits = rect
def mousePressEvent(self, event):
if self.origin.isNull():
self.origin = self.pos()
if event.button() == QtCore.Qt.LeftButton:
self.mousePos = event.pos()
def mouseMoveEvent(self, event):
if event.buttons() == QtCore.Qt.LeftButton:
self.move(self.pos() + event.pos() - self.mousePos)
def mouseReleaseEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
if not self.limits.contains(self.geometry()):
self.move(self.origin)
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.setEnabled(True)
Dialog.resize(1050, 800)
Dialog.setMinimumSize(QtCore.QSize(1050, 800))
Dialog.setMaximumSize(QtCore.QSize(1050, 800))
icon = QtGui.QIcon()
icon.addPixmap(
QtGui.QPixmap("../.designer/backup/project pic/images icon.png"),
QtGui.QIcon.Normal,
QtGui.QIcon.Off,
)
Dialog.setWindowIcon(icon)
Dialog.setStyleSheet(
"background-color: rgb(217, 217, 217);\n"
"background-color: rgb(243, 243, 243);"
)
self.BrowesImageButton = QtWidgets.QPushButton(Dialog)
self.BrowesImageButton.setGeometry(QtCore.QRect(820, 60, 200, 60))
self.BrowesImageButton.setMinimumSize(QtCore.QSize(200, 60))
self.BrowesImageButton.setMaximumSize(QtCore.QSize(200, 60))
font = QtGui.QFont()
font.setFamily("Microsoft YaHei UI")
font.setPointSize(11)
font.setBold(True)
font.setWeight(75)
self.BrowesImageButton.setFont(font)
self.BrowesImageButton.setStyleSheet("")
self.BrowesImageButton.setCheckable(True)
self.BrowesImageButton.setObjectName("BrowesImageButton")
self.groupBox = QtWidgets.QGroupBox(Dialog)
self.groupBox.setGeometry(QtCore.QRect(820, 170, 211, 131))
font = QtGui.QFont()
font.setFamily("Microsoft YaHei")
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.groupBox.setFont(font)
self.groupBox.setLayoutDirection(QtCore.Qt.LeftToRight)
self.groupBox.setObjectName("groupBox")
self.checkBox_Short = QtWidgets.QCheckBox(self.groupBox)
self.checkBox_Short.setGeometry(QtCore.QRect(20, 40, 141, 23))
font = QtGui.QFont()
font.setFamily("Adobe Heiti Std R")
font.setPointSize(10)
self.checkBox_Short.setFont(font)
self.checkBox_Short.setLayoutDirection(QtCore.Qt.LeftToRight)
self.checkBox_Short.setObjectName("checkBox_Short")
self.checkBox_Short.setEnabled(False)
self.checkBox_Long = QtWidgets.QCheckBox(self.groupBox)
self.checkBox_Long.setGeometry(QtCore.QRect(20, 80, 141, 23))
font = QtGui.QFont()
font.setFamily("Adobe Heiti Std R")
font.setPointSize(10)
self.checkBox_Long.setFont(font)
self.checkBox_Long.setLayoutDirection(QtCore.Qt.LeftToRight)
self.checkBox_Long.setObjectName("checkBox_Long")
self.checkBox_Long.setEnabled(False)
self.SegmentImageButton = QtWidgets.QPushButton(Dialog)
self.SegmentImageButton.setGeometry(QtCore.QRect(830, 330, 200, 60))
self.SegmentImageButton.setMinimumSize(QtCore.QSize(200, 60))
self.SegmentImageButton.setMaximumSize(QtCore.QSize(200, 60))
font = QtGui.QFont()
font.setFamily("Microsoft YaHei UI")
font.setPointSize(11)
font.setBold(True)
font.setWeight(75)
self.SegmentImageButton.setFont(font)
self.SegmentImageButton.setStyleSheet("")
self.SegmentImageButton.setCheckable(True)
self.SegmentImageButton.setObjectName("SegmentImageButton")
self.SegmentImageButton.setEnabled(False)
self.UserImageLbl = QtWidgets.QLabel(Dialog)
self.UserImageLbl.setGeometry(QtCore.QRect(40, 40, 750, 500))
self.UserImageLbl.setMinimumSize(QtCore.QSize(750, 500))
self.UserImageLbl.setMaximumSize(QtCore.QSize(750, 500))
self.UserImageLbl.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.UserImageLbl.setFrameShadow(QtWidgets.QFrame.Plain)
self.UserImageLbl.setLineWidth(1)
self.UserImageLbl.setMidLineWidth(0)
self.UserImageLbl.setText("")
self.UserImageLbl.setScaledContents(False)
self.UserImageLbl.setAlignment(QtCore.Qt.AlignCenter)
self.UserImageLbl.setObjectName("UserImageLbl")
self.buttonGroup = QtWidgets.QButtonGroup()
self.buttonGroup.addButton(self.checkBox_Short)
self.buttonGroup.addButton(self.checkBox_Long)
self.retranslateUi(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Cropping"))
self.BrowesImageButton.setText(_translate("Dialog", "Select Image"))
self.groupBox.setTitle(_translate("Dialog", "Choose Type"))
self.checkBox_Short.setText(_translate("Dialog", "Short "))
self.checkBox_Long.setText(_translate("Dialog", "Long "))
self.SegmentImageButton.setText(_translate("Dialog", "Segment Image"))
class Dialog(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.label_1 = DraggableLabel(self)
self.label_2 = DraggableLabel(self)
self.label_3 = DraggableLabel(self)
self.label_1.move(820, 470)
self.label_2.move(900, 470)
self.label_3.move(980, 470)
self.labels = [self.label_1, self.label_2, self.label_3]
for label in self.labels:
label.hide()
label.raise_()
self.BrowesImageButton.clicked.connect(self.setImage)
self.checkBox_Long.toggled.connect(self.setBoxSizes)
self.checkBox_Short.toggled.connect(self.setBoxSizes)
self.SegmentImageButton.clicked.connect(self.crop)
def setImage(self):
fileName, _ = QtWidgets.QFileDialog.getOpenFileName(
None, "Select Image", "", "Image Files (*.png *.jpg *jpeg *.bmp)"
) # Ask for file
if fileName: # If the user gives a file
pixmap = QtGui.QPixmap(fileName) # Setup pixmap with the provided image
pixmap = pixmap.scaled(
self.UserImageLbl.width(),
self.UserImageLbl.height(),
QtCore.Qt.KeepAspectRatio,
) # Scale pixmap
self.UserImageLbl.setPixmap(pixmap) # Set the pixmap onto the label
self.UserImageLbl.setAlignment(
QtCore.Qt.AlignCenter
) # Align the label to center
# UserImageLbl = DropLabel()
self.checkBox_Short.setEnabled(True)
self.checkBox_Long.setEnabled(True)
def setBoxSizes(self):
if self.checkBox_Short.isChecked():
self.SegmentImageButton.setEnabled(True)
boxSize = 80
else:
boxSize = 60
self.SegmentImageButton.setEnabled(True)
for label in self.labels:
label.setFixedSize(boxSize, boxSize)
label.setLimits(self.UserImageLbl.geometry())
label.show()
def crop(self):
base_rect = self.UserImageLbl.geometry()
for i, label in enumerate(self.labels, 1):
label_r = label.geometry()
res_rect = base_rect.intersected(label_r)
if not res_rect.isNull():
label.hide()
pixmap = self.grab(res_rect)
label.show()
pixmap.save("OUT{}.png".format(i))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Dialog()
w.show()
sys.exit(app.exec_())

Related

Cropping an image based on its angles with PyQt

I want to make a python script where the program shows an image that contains a rectangle or a square and then the End-user should specify four angles of this shape by drag some pointers on its angles. These pointers will be presented by the program.
Based on these angles the program should crop the shape from the rest of the image.
Example of images that the program will show:
Pointers Images:
What the user should do :
The Output of the program:
How I can do this?
I'm Working with Python3, PyQt5.
This is what I have done so far, which is the process of allowing the user to browse to select an image from his computer and upload it to the program
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QCursor
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.setEnabled(True)
Dialog.resize(1050, 800)
Dialog.setMinimumSize(QtCore.QSize(1050, 800))
Dialog.setMaximumSize(QtCore.QSize(1050, 800))
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("project pic/images LPR icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
Dialog.setWindowIcon(icon)
Dialog.setStyleSheet("background-color: rgb(217, 217, 217);\n"
"background-color: rgb(243, 243, 243);")
self.UserImageLbl = QtWidgets.QLabel(Dialog)
self.UserImageLbl.setGeometry(QtCore.QRect(130, 60, 800, 600))
self.UserImageLbl.setMinimumSize(QtCore.QSize(800, 600))
self.UserImageLbl.setMaximumSize(QtCore.QSize(800, 600))
self.UserImageLbl.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.UserImageLbl.setFrameShadow(QtWidgets.QFrame.Plain)
self.UserImageLbl.setLineWidth(1)
self.UserImageLbl.setMidLineWidth(0)
self.UserImageLbl.setText("")
self.UserImageLbl.setPixmap(QtGui.QPixmap("project pic/upn.png"))
self.UserImageLbl.setScaledContents(False)
self.UserImageLbl.setAlignment(QtCore.Qt.AlignCenter)
self.UserImageLbl.setObjectName("UserImageLbl")
self.BrowesImageButton = QtWidgets.QPushButton(Dialog)
self.BrowesImageButton.setGeometry(QtCore.QRect(430, 690, 230, 60))
self.BrowesImageButton.setMinimumSize(QtCore.QSize(230, 60))
self.BrowesImageButton.setMaximumSize(QtCore.QSize(230, 60))
font = QtGui.QFont()
font.setFamily("Microsoft YaHei UI")
font.setPointSize(11)
font.setBold(True)
font.setWeight(75)
self.BrowesImageButton.setFont(font)
self.BrowesImageButton.setStyleSheet("background-color: rgb(0, 214, 157);\n"
"background-color: rgb(0, 170, 127);")
self.BrowesImageButton.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
# self.BrowesImageButton.setStyleSheet("BrowesImageButton:hover { background-color: rgb(0, 214, 157) }" )
self.BrowesImageButton.setCheckable(True)
self.BrowesImageButton.setObjectName("BrowesImageButton")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
self.BrowesImageButton.clicked.connect(self.setImage)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", " Cropping Shapes"))
self.BrowesImageButton.setText(_translate("Dialog", "Browse Image"))
def setImage(self):
#fileName, _ = QtWidgets.QFileDialog.getOpenFileName(None, "Select Image", "", "Image Files (*.png *.jpg *jpeg *.bmp);;All Files (*)") # Ask for file
fileName, _ = QtWidgets.QFileDialog.getOpenFileName(None, "Select Image", "", "Image Files (*.png)") # Ask for file
if fileName: # If the user gives a file
pixmap = QtGui.QPixmap(fileName) # Setup pixmap with the provided image
pixmap = pixmap.scaled(self.UserImageLbl.width(), self.UserImageLbl.height(), QtCore.Qt.KeepAspectRatio) # Scale pixmap
self.UserImageLbl.setPixmap(pixmap) # Set the pixmap onto the label
self.UserImageLbl.setAlignment(QtCore.Qt.AlignCenter) # Align the label to center
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
Thanks in advance.
In this case it is better to use QGraphicsView as it allows us to add other images without the need to scale the image. In the QGraphicsView you get the points where you click on the item that has the image, and then with that information using my previous answer you get the following:
import os
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
current_dir = os.path.dirname(os.path.realpath(__file__))
point_filename = os.path.join(current_dir, "41uu2.png")
class GraphicsView(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super().__init__(QtWidgets.QGraphicsScene(), parent)
self.pixmap_item = self.scene().addPixmap(QtGui.QPixmap())
self.pixmap_item.setShapeMode(QtWidgets.QGraphicsPixmapItem.BoundingRectShape)
self.setAlignment(QtCore.Qt.AlignCenter)
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
def set_image(self, pixmap):
self.pixmap_item.setPixmap(pixmap)
self.fitInView(self.pixmap_item, QtCore.Qt.KeepAspectRatio)
class CropView(GraphicsView):
resultChanged = QtCore.pyqtSignal(QtGui.QPixmap)
def __init__(self, parent=None):
super().__init__(parent)
self.point_items = []
def mousePressEvent(self, event):
if not self.pixmap_item.pixmap().isNull():
sp = self.mapToScene(event.pos())
lp = self.pixmap_item.mapFromScene(sp)
if self.pixmap_item.contains(lp):
size = QtCore.QSize(30, 30)
height = (
self.mapToScene(QtCore.QRect(QtCore.QPoint(), size))
.boundingRect()
.size()
.height()
)
pixmap = QtGui.QPixmap(point_filename)
point_item = QtWidgets.QGraphicsPixmapItem(pixmap, self.pixmap_item)
point_item.setOffset(
-QtCore.QRect(QtCore.QPoint(), pixmap.size()).center()
)
point_item.setPos(lp)
scale = height / point_item.boundingRect().size().height()
point_item.setScale(scale)
self.point_items.append(point_item)
if len(self.point_items) == 4:
points = []
for it in self.point_items:
points.append(it.pos().toPoint())
self.crop(points)
elif len(self.point_items) == 5:
for it in self.point_items[:-1]:
self.scene().removeItem(it)
self.point_items = [self.point_items[-1]]
else:
print("outside")
super().mousePressEvent(event)
def crop(self, points):
# https://stackoverflow.com/a/55714969/6622587
polygon = QtGui.QPolygonF(points)
path = QtGui.QPainterPath()
path.addPolygon(polygon)
source = self.pixmap_item.pixmap()
r = path.boundingRect().toRect().intersected(source.rect())
pixmap = QtGui.QPixmap(source.size())
pixmap.fill(QtCore.Qt.transparent)
painter = QtGui.QPainter(pixmap)
painter.setClipPath(path)
painter.drawPixmap(QtCore.QPoint(), source, source.rect())
painter.end()
result = pixmap.copy(r)
self.resultChanged.emit(result)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setFixedSize(1050, 600)
self.left_view = CropView()
self.rigth_view = GraphicsView()
self.left_view.resultChanged.connect(self.rigth_view.set_image)
button = QtWidgets.QPushButton(self.tr("Browse Image"))
button.setStyleSheet("background-color: rgb(0, 214, 157);")
button.setFixedSize(230, 60)
font = QtGui.QFont()
font.setFamily("Microsoft YaHei UI")
font.setPointSize(11)
font.setBold(True)
font.setWeight(75)
button.setFont(font)
button.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
button.clicked.connect(self.load_image)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
lay = QtWidgets.QGridLayout(central_widget)
lay.addWidget(self.left_view, 0, 0)
lay.addWidget(self.rigth_view, 0, 1)
lay.addWidget(button, 1, 0, 1, 2, alignment=QtCore.Qt.AlignHCenter)
#QtCore.pyqtSlot()
def load_image(self):
fileName, _ = QtWidgets.QFileDialog.getOpenFileName(
None, "Select Image", "", "Image Files (*.png)"
)
if fileName:
pixmap = QtGui.QPixmap(fileName)
self.left_view.set_image(pixmap)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())

Pyqt5. Running string and clock

I have a form with to labels (clock on the top and running string on the bottom). I added linker_by_grid to form (so that all components can proportional resize when form resize).
When I run project, every seconds text in running string is twitching. If I delete linker_by_grid from form, everything is OK, but all components not autoresizing to form.
Code from QtDesigner:
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(498, 299)
self.verticalLayoutWidget = QtWidgets.QWidget(Form)
self.verticalLayoutWidget.setGeometry(QtCore.QRect(10, 10, 479, 281))
self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.label_2 = QtWidgets.QLabel(self.verticalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(15)
self.label_2.setFont(font)
self.label_2.setText("")
self.label_2.setAlignment(QtCore.Qt.AlignCenter)
self.label_2.setObjectName("label_2")
self.verticalLayout.addWidget(self.label_2)
self.tableWidget = QtWidgets.QTableWidget(self.verticalLayoutWidget)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(0)
self.tableWidget.setRowCount(0)
self.verticalLayout.addWidget(self.tableWidget)
self.label = QtWidgets.QLabel(self.verticalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(15)
self.label.setFont(font)
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.label.setText(_translate("Form", "Running string ... "))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec_()) ```
main file:
``` from PyQt5 import QtWidgets
from PyQt5.QtCore import QTimer, QTime
import sys
import untitled
class Widget(QtWidgets.QWidget):
def __init__(self):
super(Widget, self).__init__()
self.ui = untitled.Ui_Form()
self.ui.setupUi(self)
self.x = 477
self.y = self.height() - 30
self.ui.label.move(self.x, self.y)
self.timer = QTimer(self)
self.timer.timeout.connect(self.move_label_left)
self.timer.start(100)
self.timer2 = QTimer(self)
self.timer2.timeout.connect(self.show_clock)
self.timer2.start(1000)
def move_label_left(self):
if self.x == -477:
self.x = 477
self.x -= 2
self.ui.label.move(self.x, self.height() - 30)
else:
self.x -= 2
self.ui.label.move(self.x, self.height() - 30)
def show_clock(self):
time = QTime.currentTime()
text = time.toString('hh:mm:ss')
self.ui.label_2.setText(text)
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_()) ```
You need to remove the label from the layout
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5 import QtWidgets
from PyQt5.QtCore import QTimer, QTime
#import untitled
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(500, 350) #(498, 299)
# self.verticalLayoutWidget = QtWidgets.QWidget(Form)
# self.verticalLayoutWidget.setGeometry(QtCore.QRect(10, 10, 479, 281))
# self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(Form) #(self.verticalLayoutWidget)
self.verticalLayout.setContentsMargins(0, 0, 0, 50) # + 50
self.verticalLayout.setObjectName("verticalLayout")
self.label_2 = QtWidgets.QLabel(Form) #(self.verticalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(15)
self.label_2.setFont(font)
self.label_2.setText("")
self.label_2.setAlignment(QtCore.Qt.AlignCenter)
self.label_2.setObjectName("label_2")
self.verticalLayout.addWidget(self.label_2)
self.tableWidget = QtWidgets.QTableWidget(Form) #(self.verticalLayoutWidget)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(4)
self.tableWidget.setRowCount(3)
self.verticalLayout.addWidget(self.tableWidget)
# self.label = QtWidgets.QLabel(self.verticalLayoutWidget)
# font = QtGui.QFont()
# font.setPointSize(15)
# self.label.setFont(font)
# self.label.setObjectName("label")
# self.verticalLayout.addWidget(self.label)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
# self.label.setText(_translate("Form", "Running string ... "))
class Widget(QtWidgets.QWidget):
def __init__(self):
super(Widget, self).__init__()
self.ui = Ui_Form()
self.ui.setupUi(self)
self.ui.tableWidget.setAlternatingRowColors(True) # +
self.ui.tableWidget.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch) # +
self.labelMove = QtWidgets.QLabel("Running string ... ", self) # +
font = QtGui.QFont() # +
font.setPointSize(15) # +
self.labelMove.setFont(font) # +
self.x = self.width() #477
self.y = self.height() - 30
self.labelMove.move(self.x, self.y)
self.timer = QTimer(self)
self.timer.timeout.connect(self.move_label_left)
self.timer.start(15) # 100
self.timer2 = QTimer(self)
self.timer2.timeout.connect(self.show_clock)
self.timer2.start(1000)
def move_label_left(self):
if self.x <= -150: # 477
self.x = self.width() # 477
self.x -= 1
self.labelMove.move(self.x, self.height() - 30)
else:
self.x -= 1
self.labelMove.move(self.x, self.height() - 30)
self.labelMove.adjustSize() # +++
def show_clock(self):
time = QTime.currentTime()
text = time.toString('hh:mm:ss')
self.ui.label_2.setText(text)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())

PySide2 composite widget Hover Effect

How to animate position,scale or any other attributes of composed elements inside custom widget, on mouse pointer enters or leaves the QListWidgetItem ?
(see reference image below)
And is there any better way to manage space around ListWidgetItem ?
item_widget.sizeHint() gives unwanted extra space, which is why i added hard coded value to setSizeHint.
ProductMainWindow.py
from PySide2 import QtCore, QtGui, QtWidgets
import productThumbnailWidget
import sys
sys.path.append('E:/code')
class prodMainWindowUI(QtWidgets.QMainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.setupUi(self)
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.productListWidget = QtWidgets.QListWidget(self.centralwidget)
self.productListWidget.setObjectName("productListWidget")
self.productListWidget.setViewMode(QtWidgets.QListWidget.IconMode)
self.productListWidget.setIconSize(QtCore.QSize(256,256))
self.productListWidget.setResizeMode(QtWidgets.QListWidget.Adjust)
self.productListWidget.setMovement(QtWidgets.QListWidget.Static) # disable drag and drop
self.productListWidget.setGridSize(QtCore.QSize(256 + 5, 256 + 5))
self.verticalLayout.addWidget(self.productListWidget)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
for i in range(6):
item = QtWidgets.QListWidgetItem(self.productListWidget)
item_widget = productThumbnailWidget.productThumbWidget()
#item.setSizeHint(item_widget.sizeHint())
item.setSizeHint(QtCore.QSize(256,256))
self.productListWidget.addItem(item)
self.productListWidget.setItemWidget(item, item_widget)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtWidgets.QApplication.translate("MainWindow", "MainWindow", None, -1))
app = QtWidgets.QApplication(sys.argv)
prodUI = prodMainWindowUI()
prodUI.show()
sys.exit(app.exec_())
productThumbnailWidget
from PySide2 import QtCore, QtGui, QtWidgets
class productThumbWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(productThumbWidget, self).__init__(parent)
self.setObjectName("Form")
self.resize(256, 256)
self.setMinimumSize(QtCore.QSize(256, 256))
self.setMaximumSize(QtCore.QSize(256, 256))
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setSpacing(0)
self.verticalLayout.setObjectName("verticalLayout")
self.frame = QtWidgets.QFrame()
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.thumbnailLabel = QtWidgets.QLabel("", self.frame)
self.thumbnailLabel.setObjectName("thumbnailLabel")
self.thumbnailLabel.setScaledContents(False)
self.thumbnailLabel.setGeometry(QtCore.QRect(0, 0, 256, 256))
self.thumbnailLabel.setMinimumSize(QtCore.QSize(256, 256))
self.thumbnailLabel.setMaximumSize(QtCore.QSize(256, 256))
self.thumbnailLabel.setPixmap(QtGui.QPixmap("E:/code/android.png"))
self.backgroundLabel = QtWidgets.QLabel("", self.frame)
self.backgroundLabel.setObjectName("backgroundLabel")
self.backgroundLabel.setGeometry(QtCore.QRect(0, 206, 256, 50))
self.backgroundLabel.setMinimumSize(QtCore.QSize(256, 50))
self.backgroundLabel.setMaximumSize(QtCore.QSize(256, 50))
self.backgroundLabel.setStyleSheet("QLabel#backgroundLabel{\n"
" background: #32353B;\n"
"}")
self.titleLabel = QtWidgets.QLabel("Title", self.frame)
self.titleLabel.setObjectName("titleLabel")
self.titleLabel.setGeometry(QtCore.QRect(10, 218, 246, 25))
self.titleLabel.setMinimumSize(QtCore.QSize(246, 25))
self.titleLabel.setMaximumSize(QtCore.QSize(246, 25))
font = QtGui.QFont()
font.setFamily("SF Pro Display")
font.setPointSize(16)
font.setWeight(75)
font.setBold(True)
self.titleLabel.setFont(font)
self.titleLabel.setStyleSheet("QLabel#titleLabel {\n"
" color: #FFFFFF;\n"
"}")
self.verticalLayout.addWidget(self.frame)
self.setLayout(self.verticalLayout)
Output
The solution is to animate the position of the rectangle using QPropertyAnimation, and to activate the animations using the events QEvent::Enter and QEvent::Leave:
import shiboken2
from PySide2 import QtCore, QtGui, QtWidgets
class RectangleHoverEffect(QtCore.QObject):
def __init__(self, rectangle, parent):
super().__init__(parent)
if not isinstance(rectangle, QtWidgets.QWidget):
raise TypeError(f"{rectangle} must be a QWidget")
if rectangle.parent() is None:
raise ValueError(f"{rectangle} must have a parent")
self.m_rectangle = rectangle
self.m_rectangle.parent().installEventFilter(self)
self.m_animation = QtCore.QPropertyAnimation(
self,
targetObject=self.m_rectangle,
propertyName=b"pos",
duration=300,
easingCurve=QtCore.QEasingCurve.OutQuad,
)
def eventFilter(self, obj, event):
if shiboken2.isValid(self.m_rectangle):
if self.m_rectangle.parent() is obj:
y0 = self.m_rectangle.parent().height()
y1 = self.m_rectangle.parent().height() - self.m_rectangle.height()
if event.type() == QtCore.QEvent.Enter:
self._start_animation(y0, y1)
elif event.type() == QtCore.QEvent.Leave:
self._start_animation(y1, y0)
return super().eventFilter(obj, event)
def _start_animation(self, y0, y1):
self.m_animation.setStartValue(QtCore.QPoint(0, y0))
self.m_animation.setEndValue(QtCore.QPoint(0, y1))
self.m_animation.start()
class ThumbWidget(QtWidgets.QFrame):
def __init__(self, title, pixmap, parent=None):
super().__init__(parent)
self.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.setFrameShadow(QtWidgets.QFrame.Raised)
pixmap_label = QtWidgets.QLabel(pixmap=pixmap, scaledContents=True)
title_label = QtWidgets.QLabel(title)
title_label.setStyleSheet("""color: #FFFFFF""")
font = QtGui.QFont()
font.setFamily("SF Pro Display")
font.setPointSize(16)
font.setWeight(75)
font.setBold(True)
title_label.setFont(font)
background_label = QtWidgets.QLabel(pixmap_label)
background_label.setStyleSheet("background: #32353B;")
background_label.setFixedSize(self.width(), 50)
background_label.move(0, self.height())
background_lay = QtWidgets.QVBoxLayout(background_label)
background_lay.addWidget(title_label)
self.setFixedSize(256, 256)
lay = QtWidgets.QVBoxLayout(self)
lay.setContentsMargins(0, 0, 0, 0)
lay.setSpacing(0)
lay.addWidget(pixmap_label)
effect = RectangleHoverEffect(background_label, self)
class ProductMainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.product_listwidget = QtWidgets.QListWidget(
viewMode=QtWidgets.QListWidget.IconMode,
iconSize=QtCore.QSize(256, 256),
resizeMode=QtWidgets.QListWidget.Adjust,
movement=QtWidgets.QListWidget.Static,
)
self.product_listwidget.setGridSize(QtCore.QSize(256 + 5, 256 + 5))
for i in range(6):
item = QtWidgets.QListWidgetItem()
item_widget = ThumbWidget(f"Title {i}", QtGui.QPixmap("E:/code/android.png"))
item.setSizeHint(QtCore.QSize(256, 256))
self.product_listwidget.addItem(item)
self.product_listwidget.setItemWidget(item, item_widget)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
lay = QtWidgets.QVBoxLayout(central_widget)
lay.addWidget(self.product_listwidget)
self.resize(960, 480)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = ProductMainWindow()
w.show()
sys.exit(app.exec_())

How to return a value from Dialog to Main?

I have two files and I want to return an array from Dialog of Bitacora to Main. In some part of the Main code calls Bitacora. Bitacora have a textEdit. I need to return these values.
I hope that you can help me guys.
File: Main.py
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import Qt
from dbFuncs import *
from demoUI import *
from PandasModel import *
from dataLogger import *
from bitacorasend import Ui_Dialog
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super(MainWindow, self).__init__()
#QtWidgets.QMainWindow.__init__(self, *args, **kwargs)
self.setupUi(self)
'''Variables for DB'''
'''Table Config'''
self.dataTable.setColumnCount(1)
self.dataTable.setRowCount(5)
self.dataTable.setHorizontalHeaderLabels(["Medición"])
self.dataTable.horizontalHeaderItem(0).setTextAlignment(Qt.AlignHCenter)
self.dataTable.horizontalHeader().setStretchLastSection(True)
self.dataTable.verticalHeader().setStretchLastSection(True)
'''Buttons signals'''
self.saveButton.clicked.connect(self.savePressed)
def bitacora(self):
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog,["data","data","data","data"])
Dialog.exec_()
def savePressed(self):
self.bitacora()
if __name__ == "__main__":
app = QtWidgets.QApplication([])
window = MainWindow()
window.show()
app.exec_()
File: Bitacora.py
from PyQt5 import QtCore, QtGui, QtWidgets
#import time
class Ui_Dialog(object):
def setupUi(self, Dialog, datos):
self.data = datos
self.Dialog = Dialog
Dialog.setObjectName("Dialog")
Dialog.resize(617, 405)
self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
self.verticalLayout.setObjectName("verticalLayout")
self.label = QtWidgets.QLabel(Dialog)
font = QtGui.QFont()
font.setPointSize(10)
self.label.setFont(font)
self.label.setAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignHCenter)
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
self.label_2 = QtWidgets.QLabel(Dialog)
font = QtGui.QFont()
font.setPointSize(16)
font.setBold(True)
font.setWeight(75)
self.label_2.setFont(font)
self.label_2.setAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignTop)
self.label_2.setObjectName("label_2")
self.verticalLayout.addWidget(self.label_2)
self.label_5 = QtWidgets.QLabel(Dialog)
self.label_5.setAlignment(QtCore.Qt.AlignCenter)
self.label_5.setObjectName("label_5")
self.verticalLayout.addWidget(self.label_5)
self.label_3 = QtWidgets.QLabel(Dialog)
font = QtGui.QFont()
font.setPointSize(12)
font.setBold(True)
font.setWeight(75)
self.label_3.setFont(font)
self.label_3.setAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft)
self.label_3.setObjectName("label_3")
self.verticalLayout.addWidget(self.label_3)
self.textEdit = QtWidgets.QTextEdit(Dialog)
self.textEdit.setMaximumSize(QtCore.QSize(16777215, 100))
self.textEdit.setObjectName("textEdit")
self.verticalLayout.addWidget(self.textEdit)
self.label_4 = QtWidgets.QLabel(Dialog)
font = QtGui.QFont()
font.setPointSize(12)
font.setBold(True)
font.setWeight(75)
self.label_4.setFont(font)
self.label_4.setAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft)
self.label_4.setObjectName("label_4")
self.verticalLayout.addWidget(self.label_4)
self.textEdit_2 = QtWidgets.QTextEdit(Dialog)
self.textEdit_2.setObjectName("textEdit_2")
self.verticalLayout.addWidget(self.textEdit_2)
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.verticalLayout.addWidget(self.buttonBox)
self.retranslateUi(Dialog)
self.buttonBox.accepted.connect(self.save)
self.buttonBox.rejected.connect(Dialog.reject)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def save(self):
print("Return here")
self.Dialog.close()
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.label.setText(_translate("Dialog", "Punto Fuera de Control"))
self.label_2.setText(_translate("Dialog", "Bitacora de Proceso"))
self.label_5.setText(_translate("Dialog", "Cualquier cambio en mano de obra, materiales, medio ambiente, métodos o máquinas debe ser anotado"))
self.label_3.setText(_translate("Dialog", "Causa:"))
self.textEdit.setText(_translate("Dialog", ""))
self.label_4.setText(_translate("Dialog", "Correcciones:"))
self.textEdit_2.setHtml(_translate("Dialog", ""))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
Try it:
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import Qt
#from dbFuncs import *
#from demoUI import *
#from PandasModel import *
#from dataLogger import *
#import time
#from bitacorasend import Ui_Dialog
class Ui_Dialog(object):
def setupUi(self, Dialog, datos):
self.data = datos
self.Dialog = Dialog
Dialog.setObjectName("Dialog")
Dialog.resize(617, 405)
self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
self.verticalLayout.setObjectName("verticalLayout")
self.label = QtWidgets.QLabel(Dialog)
font = QtGui.QFont()
font.setPointSize(10)
self.label.setFont(font)
self.label.setAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignHCenter)
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
self.label_2 = QtWidgets.QLabel(Dialog)
font = QtGui.QFont()
font.setPointSize(16)
font.setBold(True)
font.setWeight(75)
self.label_2.setFont(font)
self.label_2.setAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignTop)
self.label_2.setObjectName("label_2")
self.verticalLayout.addWidget(self.label_2)
self.label_5 = QtWidgets.QLabel(Dialog)
self.label_5.setAlignment(QtCore.Qt.AlignCenter)
self.label_5.setObjectName("label_5")
self.verticalLayout.addWidget(self.label_5)
self.label_3 = QtWidgets.QLabel(Dialog)
font = QtGui.QFont()
font.setPointSize(12)
font.setBold(True)
font.setWeight(75)
self.label_3.setFont(font)
self.label_3.setAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft)
self.label_3.setObjectName("label_3")
self.verticalLayout.addWidget(self.label_3)
self.textEdit = QtWidgets.QTextEdit(Dialog)
self.textEdit.setMaximumSize(QtCore.QSize(16777215, 100))
self.textEdit.setObjectName("textEdit")
self.verticalLayout.addWidget(self.textEdit)
self.label_4 = QtWidgets.QLabel(Dialog)
font = QtGui.QFont()
font.setPointSize(12)
font.setBold(True)
font.setWeight(75)
self.label_4.setFont(font)
self.label_4.setAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft)
self.label_4.setObjectName("label_4")
self.verticalLayout.addWidget(self.label_4)
self.textEdit_2 = QtWidgets.QTextEdit(Dialog)
self.textEdit_2.setObjectName("textEdit_2")
self.verticalLayout.addWidget(self.textEdit_2)
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.verticalLayout.addWidget(self.buttonBox)
self.retranslateUi(Dialog)
self.buttonBox.accepted.connect(self.save)
self.buttonBox.rejected.connect(Dialog.reject)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def save(self):
print("Return here")
self.Dialog.close()
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.label.setText(_translate("Dialog", "Punto Fuera de Control"))
self.label_2.setText(_translate("Dialog", "Bitacora de Proceso"))
self.label_5.setText(_translate("Dialog", "Cualquier cambio en mano de obra, materiales, medio ambiente, métodos o máquinas debe ser anotado"))
self.label_3.setText(_translate("Dialog", "Causa:"))
self.textEdit.setText(_translate("Dialog", ""))
self.label_4.setText(_translate("Dialog", "Correcciones:"))
self.textEdit_2.setHtml(_translate("Dialog", ""))
class MainWindow(QtWidgets.QMainWindow): #, Ui_MainWindow):
def __init__(self):
super(MainWindow, self).__init__()
#QtWidgets.QMainWindow.__init__(self, *args, **kwargs)
# self.setupUi(self)
'''Variables for DB'''
centralWidget = QtWidgets.QWidget(self)
self.setCentralWidget(centralWidget)
self.dataTable = QtWidgets.QTableWidget(self)
self.saveButton = QtWidgets.QPushButton("saveButton", self)
layout = QtWidgets.QGridLayout(centralWidget)
layout.addWidget(self.dataTable)
layout.addWidget(self.saveButton)
'''Table Config'''
self.dataTable.setColumnCount(1)
self.dataTable.setRowCount(5)
self.dataTable.setHorizontalHeaderLabels(["Medición"])
self.dataTable.horizontalHeaderItem(0).setTextAlignment(Qt.AlignHCenter)
self.dataTable.horizontalHeader().setStretchLastSection(True)
self.dataTable.verticalHeader().setStretchLastSection(True)
'''Buttons signals'''
self.saveButton.clicked.connect(self.savePressed)
def bitacora(self):
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog,["data","data","data","data"])
Dialog.exec_()
print(ui.textEdit.toPlainText()) # <---
print(ui.textEdit_2.toPlainText()) # <---
def savePressed(self):
self.bitacora()
if __name__ == "__main__":
app = QtWidgets.QApplication([])
window = MainWindow()
window.show()
app.exec_()

Display a down arrow in a widget

I want to display a downward facing arrow (or any shape really) in QT designer between two lineEdits. This seems simple, but I can't seem to find an answer. I have code below that shows what I am trying to do. Any help is greatly appreciated!
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QPainter, QBrush, QPen
from PyQt5.QtCore import Qt
class Ui_Frame(object):
def setupUi(self, Frame):
Frame.setObjectName("Frame")
Frame.resize(472, 408)
Frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
Frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.verticalLayout = QtWidgets.QVBoxLayout(Frame)
self.verticalLayout.setObjectName("verticalLayout")
self.lineEdit = QtWidgets.QLineEdit(Frame)
self.lineEdit.setAlignment(QtCore.Qt.AlignCenter)
self.lineEdit.setObjectName("lineEdit")
self.verticalLayout.addWidget(self.lineEdit)
self.frame = QtWidgets.QFrame(Frame)
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.frame)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.frame_3 = QtWidgets.QFrame(self.frame)
self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_3.setObjectName("frame_3")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.frame_3)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.label_2 = QtWidgets.QLabel(self.frame_3)
self.label_2.setObjectName("label_2")
self.horizontalLayout_2.addWidget(self.label_2)
self.lineEdit_4 = QtWidgets.QLineEdit(self.frame_3)
self.lineEdit_4.setObjectName("lineEdit_4")
self.horizontalLayout_2.addWidget(self.lineEdit_4)
self.verticalLayout_2.addWidget(self.frame_3)
# I would like to paint a shape on this frame (frame_paint) using method paintEvent
self.frame_paint = QtWidgets.QFrame(self.frame)
self.frame_paint.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_paint.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_paint.setObjectName("frame_paint")
self.verticalLayout_2.addWidget(self.frame_paint)
self.frame_2 = QtWidgets.QFrame(self.frame)
self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_2.setObjectName("frame_2")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame_2)
self.horizontalLayout.setObjectName("horizontalLayout")
self.label = QtWidgets.QLabel(self.frame_2)
self.label.setObjectName("label")
self.horizontalLayout.addWidget(self.label)
self.lineEdit_3 = QtWidgets.QLineEdit(self.frame_2)
self.lineEdit_3.setObjectName("lineEdit_3")
self.horizontalLayout.addWidget(self.lineEdit_3)
self.verticalLayout_2.addWidget(self.frame_2)
self.verticalLayout.addWidget(self.frame)
self.retranslateUi(Frame)
QtCore.QMetaObject.connectSlotsByName(Frame)
def retranslateUi(self, Frame):
_translate = QtCore.QCoreApplication.translate
Frame.setWindowTitle(_translate("Frame", "Frame"))
self.lineEdit.setText(_translate("Frame", "(Name of research project)"))
self.label_2.setText(_translate("Frame", "Level 1:"))
self.label.setText(_translate("Frame", "Level 2:"))
### I want this paintEvent to go to the self.frame_paint
def paintEvent(self, e):
painter = QPainter(self)
painter.setPen(QPen(Qt.black, 10, Qt.SolidLine))
painter.drawRect(100, 15, 400, 200)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Frame = QtWidgets.QFrame()
ui = Ui_Frame()
ui.setupUi(Frame)
Frame.show()
sys.exit(app.exec_())
After some time, I figured it out. I was missing the whole thing about having two py files and implementing painting on a scene. Here is my code that works.
class MainWindow_RUA(QtWidgets.QMainWindow, Ui_MainWindow_RUA):
def __init__(self, parent=None):
super(MainWindow_RUA, self).__init__(parent)
self.setupUi(self)
scene = Painter()
self.graphicsView.setScene(scene)
class Painter(QtWidgets.QGraphicsScene):
def __init__(self, parent=None):
super().__init__(parent)
pen = QtGui.QPen(QtGui.QColor(QtCore.Qt.black))
pen.setWidth(2)
brush = QtGui.QBrush(pen.color().darker(150))
self.addLine(100, 200, 100, 100, pen)
self.addLine(85, 175, 100, 200, pen)
self.addLine(100, 200, 115, 175, pen)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
application = MainWindow_RUA()
application.show()
sys.exit(app.exec_())

Categories