Using draggable QLabel for cropping - python

I am trying to use draggable QLabels for cropping an image. The basic idea of my code is segmenting characters in an image.
So, the user will first upload an image contains three characters to the program.
Then, he will specify the type of the plate, is it short or long by checking on the suitable checkbox. Based on the checkbox, three boxes (QLabels) with specific size will be shown to the user so he can drag each box on a character in the uploaded image. Once the user is finished placing the boxes on the characters, he can click on the Segment button to apply the cropping operation. The final result will be three images of the cropped characters.
I have done from the program interface and some functionality, However, I'm facing a problem with darg and cropping functions. I have tried different ways with dragging boxes (QLabels) but it's not working with me. I really don't know what's wrong in my code :(. I'm using python 3 and PyQt5.
This is my code:
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
boxes_items = []
#=========================================================================
class DraggableLabel(QLabel):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
event.accept()
event.acceptProposedAction()
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
event.accept()
self.setCursor(QtGui.QCursor(QtCore.Qt.CloseHandCursor))
self.drag_start_position = event.pos()
def mouseMoveEvent(self, event):
if not (event.buttons() & Qt.LeftButton):
return
if (event.pos() - self.drag_start_position).manhattanLength() < QApplication.startDragDistance():
return
drag = QDrag(self)
'''
mimedata = QMimeData()
#mimedata.setText(self.text())
mimedata.setImageData(self.pixmap().toImage())
drag.setMimeData(mimedata)
pixmap = QPixmap(self.size())
painter = QPainter(pixmap)
painter.drawPixmap(self.rect(), self.grab())
painter.end()
drag.setPixmap(pixmap)
'''
drag.setHotSpot(event.pos())
drag.exec_(Qt.CopyAction | Qt.MoveAction)
'''
class DropLabel(QLabel):
def __init__(self, *args, **kwargs):
QLabel.__init__(self, *args, **kwargs)
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
if event.mimeData().hasText():
event.acceptProposedAction()
def dropEvent(self, event):
pos = event.pos()
self.setCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
# text = event.mimeData().text()
# self.setText(text)
event.acceptProposedAction()
'''
#==========================================================================
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 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);")
# Dialog.setAcceptDrops(True)
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.label = QtWidgets.QLabel(Dialog)
self.label.setGeometry(QtCore.QRect(980, 470, 45, 45))
self.label.setMinimumSize(QtCore.QSize(45, 45))
self.label.setMaximumSize(QtCore.QSize(45, 45))
self.label.setCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self.label.setMouseTracking(True)
self.label.setAcceptDrops(True)
self.label.setStyleSheet("border-color: rgb(238, 0, 0); border-width : 2.0px; border-style:inset;")
self.label.setFrameShape(QtWidgets.QFrame.Box)
self.label.setLineWidth(2)
self.label.setText("")
self.label.setObjectName("label")
self.label.hide()
'''
self.graphicsView = QtWidgets.QGraphicsView(Dialog)
self.graphicsView.setGeometry(QtCore.QRect(40, 40, 750, 500))
self.graphicsView.setMinimumSize(QtCore.QSize(750, 500))
self.graphicsView.setMaximumSize(QtCore.QSize(750, 500))
self.graphicsView.setObjectName("graphicsView")
'''
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.label_2 = QtWidgets.QLabel(Dialog)
self.label_2.setGeometry(QtCore.QRect(900, 470, 45, 45))
self.label_2.setMinimumSize(QtCore.QSize(45, 45))
self.label_2.setMaximumSize(QtCore.QSize(45, 45))
self.label_2.setCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self.label_2.setMouseTracking(True)
self.label_2.setAcceptDrops(True)
self.label_2.setStyleSheet("border-color: rgb(238, 0, 0); border-width : 2.0px; border-style:inset;")
self.label_2.setFrameShape(QtWidgets.QFrame.Box)
self.label_2.setLineWidth(2)
self.label_2.setText("")
self.label_2.setObjectName("label_2")
self.label_2.hide()
self.label_3 = QtWidgets.QLabel(Dialog)
self.label_3.setGeometry(QtCore.QRect(820, 470, 45, 45))
self.label_3.setMinimumSize(QtCore.QSize(45, 45))
self.label_3.setMaximumSize(QtCore.QSize(45, 45))
self.label_3.setCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self.label_3.setMouseTracking(True)
self.label_3.setAcceptDrops(True)
self.label_3.setStyleSheet("border-color: rgb(238, 0, 0); border-width : 2.0px; border-style:inset;")
self.label_3.setFrameShape(QtWidgets.QFrame.Box)
self.label_3.setLineWidth(2)
self.label_3.setText("")
self.label_3.setObjectName("label_3")
self.label_3.hide()
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
#Add labels in boxes items list
boxes_items.append(self.label)
boxes_items.append(self.label_2)
boxes_items.append(self.label_3)
#=================================== Calling =======================
self.BrowesImageButton.clicked.connect(self.setImage)
self.checkBox_Short.stateChanged.connect(self.Change_the_Checkbox_Short_Function)
self.checkBox_Long.stateChanged.connect(self.Change_the_Checkbox_Long_Function)
#=================================== Functions =========================
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 Plate Type"))
self.checkBox_Short.setText(_translate("Dialog", "Short Plate"))
self.checkBox_Long.setText(_translate("Dialog", "Long Plate"))
self.SegmentImageButton.setText(_translate("Dialog", "Segment Image"))
self.label.setToolTip(_translate("Dialog", "Drage it on first charecter"))
self.label_2.setToolTip(_translate("Dialog", "Drage it on second charecter"))
self.label_3.setToolTip(_translate("Dialog", "Drage it on third charecter"))
#=================================================================================
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 Change_the_Checkbox_Short_Function(self):
if self.checkBox_Short.isChecked():
self.checkBox_Long.setEnabled(False)
self.SegmentImageButton.setEnabled(True)
# Presenting 3 boxes 45x45 hear
for box_item in boxes_items:
#box_item.setDragEnabled(True)
box_item.setMinimumSize(QtCore.QSize(45, 45))
box_item.setMaximumSize(QtCore.QSize(45, 45))
box_item.show()
box_item = DraggableLabel()
else:
self.checkBox_Long.setEnabled(True)
for box_item in boxes_items:
box_item.hide()
#========================================================================
def Change_the_Checkbox_Long_Function(self):
if self.checkBox_Long.isChecked():
self.checkBox_Short.setEnabled(False)
self.SegmentImageButton.setEnabled(True)
# Presenting 3 boxes 40x40 hear
for box_item in boxes_items:
# box_item.setDragEnabled(True)
box_item.setMinimumSize(QtCore.QSize(40, 40))
box_item.setMaximumSize(QtCore.QSize(40, 40))
box_item.show()
box_item = DraggableLabel()
#for box_item in Sboxes_items:
#DraggableLabel(box_item)
else:
self.checkBox_Short.setEnabled(True)
for box_item in boxes_items:
box_item.hide()
#==========================================================================
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_())
I hope I can find someone who can help me with that.
Thanks in advance.

I believe you are a bit confused about how drag and drop works, but the most important thing is that you don't need "actual" drag and drop for what you want to achieve.
In this example I added the draggable boxes instead of the labels, and they are free to be moved within the image rectangle. I had to do some modifications to your original code, because it was a bit confusing and had some logic that simply didn't work.
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 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);")
# Dialog.setAcceptDrops(True)
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 = 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)
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():
boxSize = 40
else:
boxSize = 45
for label in self.labels:
label.setFixedSize(boxSize, boxSize)
label.setLimits(self.UserImageLbl.geometry())
label.show()

Related

I am trying to load the homescreen after the splashscreen

I am trying to load my homescreen after the splashscreen. Upon running the code, the splashscreen manages to load but it stops there. How do I fix this?
This is my SplashScreen class
class SplashScreen(QWidget):
def __init__(self):
super().__init__()
self.setFixedSize(700, 350)
self.setWindowFlag(Qt.FramelessWindowHint)
self.setAttribute(Qt.WA_TranslucentBackground)
self.counter = 0
self.n = 100
self.initUI()
self.timer = QTimer()
self.timer.timeout.connect(self.loading)
self.timer.start(30)
def initUI(self):
# layout to display splash scrren frame
layout = QVBoxLayout()
self.setLayout(layout)
# splash screen frame
self.frame = QFrame()
layout.addWidget(self.frame)
# splash screen title
self.title_label = QLabel(self.frame)
self.title_label.setObjectName('title_label')
self.title_label.resize(690, 120)
self.title_label.move(0, 5) # x, y
self.title_label.setText('Splash Screen')
self.title_label.setAlignment(Qt.AlignCenter)
# splash screen title description
self.description_label = QLabel(self.frame)
self.description_label.resize(690, 40)
self.description_label.move(0, self.title_label.height())
self.description_label.setObjectName('desc_label')
self.description_label.setText('<b>Splash Screen PyQt-5</b>')
self.description_label.setAlignment(Qt.AlignCenter)
# splash screen pogressbar
self.progressBar = QProgressBar(self.frame)
self.progressBar.resize(self.width() - 200 - 10, 50)
self.progressBar.move(100, 180) # self.description_label.y()+130
self.progressBar.setAlignment(Qt.AlignCenter)
self.progressBar.setFormat('%p%')
self.progressBar.setTextVisible(True)
self.progressBar.setRange(0, self.n)
self.progressBar.setValue(20)
# spash screen loading label
self.loading_label = QLabel(self.frame)
self.loading_label.resize(self.width() - 10, 50)
self.loading_label.move(0, self.progressBar.y() + 70)
self.loading_label.setObjectName('loading_label')
self.loading_label.setAlignment(Qt.AlignCenter)
self.loading_label.setText('Loading...')
This is the function that lets the splashscreen load and launch the WindowApp class but it does not work. What I mean by does not work I meant that it does not load the WindowApp. It just closes.
def loading(self):
# set progressbar value
self.progressBar.setValue(self.counter)
# stop progress if counter
# is greater than n and
# display main window app
if self.counter >= self.n:
self.timer.stop()
self.close()
MainWindow = QtWidgets.QMainWindow()
ui = WindowApp()
ui.setupUi(MainWindow)
MainWindow.show()
self.counter += 1
This is my main window
class WindowApp(QMainWindow):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1006, 654)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(10, 10, 981, 641))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(10)
self.label.setFont(font)
self.label.setText("")
self.label.setPixmap(QtGui.QPixmap("../pygui/Homescreen.png"))
self.label.setScaledContents(True)
self.label.setWordWrap(False)
self.label.setObjectName("label")
self.infoBtn = QtWidgets.QPushButton(self.centralwidget)
self.infoBtn.setGeometry(QtCore.QRect(120, 550, 181, 41))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(15)
self.infoBtn.setFont(font)
self.infoBtn.setStyleSheet("border-radius: 10px;\n"
"border-color: 2px solid gray;\n"
"background-color: rgb(255, 255, 255);")
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("icons/info_icon.png"),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.infoBtn.setIcon(icon)
self.infoBtn.setObjectName("infoBtn")
self.startBtn = QtWidgets.QPushButton(self.centralwidget)
self.startBtn.setGeometry(QtCore.QRect(310, 270, 431, 111))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(28)
self.startBtn.setFont(font)
self.startBtn.setStyleSheet("background-color: #305E6C;\n"
"color: white;\n"
"border-radius: 10px;\n"
"border: 2px solid white")
self.startBtn.setObjectName("startBtn")
self.contactsBtn = QtWidgets.QPushButton(self.centralwidget)
self.contactsBtn.setGeometry(QtCore.QRect(720, 30, 101, 101))
self.contactsBtn.setStyleSheet("\n"
"background-color: #121212;\n"
"border-radius: 50%;\n"
"border: 2px solid white;")
self.contactsBtn.setText("")
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap("icons/typcn_contacts.png"),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.contactsBtn.setIcon(icon1)
self.contactsBtn.setIconSize(QtCore.QSize(40, 40))
self.contactsBtn.setObjectName("contactsBtn")
self.dateBtn = QtWidgets.QPushButton(self.centralwidget)
self.dateBtn.setGeometry(QtCore.QRect(840, 30, 101, 101))
self.dateBtn.setStyleSheet("\n"
"background-color: #121212;\n"
"border-radius: 50%;\n"
"border: 2px solid white;")
self.dateBtn.setText("")
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap("icons/Group.png"),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.dateBtn.setIcon(icon2)
self.dateBtn.setIconSize(QtCore.QSize(40, 40))
self.dateBtn.setObjectName("dateBtn")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1006, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.infoBtn.clicked.connect(partial(self.show_popup))
self.dateBtn.clicked.connect(self.openDateWindow)
self.startBtn.clicked.connect(self.openDriveWindow)
self.contactsBtn.clicked.connect(self.openContactWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.infoBtn.setText(_translate("MainWindow", "About"))
self.startBtn.setText(_translate("MainWindow", "Driving Mode"))
def show_popup(self):
msg = QMessageBox()
msg.setWindowTitle('About Us')
msg.setText('Testing')
msg.setIcon(QMessageBox.Information)
x = msg.exec_()
def openDateWindow(self, MainWindow):
self.window = QtWidgets.QMainWindow()
self.ui = Ui_DateWindow()
self.ui.setupUi(self.window, MainWindow)
self.window.show()
MainWindow.hide()
def openDriveWindow(self, MainWindow):
self.window = QtWidgets.QMainWindow()
self.ui = Ui_DriveWindow()
self.ui.setupUi(self.window, MainWindow)
self.window.show()
MainWindow.hide()
def openContactWindow(self, MainWindow):
self.window = QtWidgets.QMainWindow()
self.ui = Ui_ContactWindow()
self.ui.setupUi(self.window, MainWindow)
self.window.show()
MainWindow.hide()
I have tried changing this to WindowApp() just to check if the MainWindow has any problems but it manages to load without the splashscreen.
app = QApplication(sys.argv)
splash = SplashScreen()
splash.show()
sys.exit(app.exec_())
Check my answer from this previous post that I think will help you.
You can show the splash screen and when the splash screen closes then you can show your main window. It's similar to the login window from this previous question
But if you want to keep implementing your code the way you have it I think I know the problem.
You call a method which creates the QMainWindow and calls the .show() for that QMainWindow. Once the method is done the variables in that method are garbage collected and so is your QMainWindow object. The way to keep the reference and prevent those variables from getting garbage collected is by making it a class variable by adding self. in front of the variable.
I would maybe restructure a bit and do something like this:
if __name__ == "__main__":
app = QApplication(sys.argv)
splash = SplashScreen()
splash_closed = splash.exec_()
if splash_closed:
window = WindowApp()
window.show()
sys.exit(app.exec_())
Where the splashscreen is now a QDialog and when you're done loading you close the dialog with self.accept() instead of trying to show a new window:
class SplashScreen(QDialog):
def __init__(self):
super().__init__()
self.setFixedSize(700, 350)
self.setWindowFlag(Qt.FramelessWindowHint)
self.setAttribute(Qt.WA_TranslucentBackground)
self.counter = 0
self.n = 100
self.initUI()
self.timer = QTimer()
self.timer.timeout.connect(self.loading)
self.timer.start(30)
def initUI(self):
...
def loading(self):
# set progressbar value
self.progressBar.setValue(self.counter)
# stop progress if counter
# is greater than n and
# display main window app
if self.counter >= self.n:
self.timer.stop()
self.accept()
self.counter += 1
And you should also use the __init__ method on your main window and maybe move all the self.setupUI code in there, or just do something like this:
class WindowApp(QMainWindow):
def __init__(self):
QtWidgets.QDialog.__init__(self)
self.setupUi(self)
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1006, 654)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
Hope this helps
import sys
from PyQt5.QtWidgets import QMainWindow, QDialog, QApplication
from PyQt5.QtWidgets import QPushButton, QVBoxLayout, QFrame, QLabel, QProgressBar
from PyQt5.QtWidgets import QWidget
from PyQt5 import QtCore, QtGui
from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt, QTimer
class SplashScreen(QWidget):
def __init__(self):
super().__init__()
self.setFixedSize(700, 350)
self.setWindowFlag(Qt.FramelessWindowHint)
self.setAttribute(Qt.WA_TranslucentBackground)
self.counter = 0
self.n = 100
self.initUI()
self.timer = QTimer()
self.timer.timeout.connect(self.loading)
self.timer.start(30)
def initUI(self):
# layout to display splash scrren frame
layout = QVBoxLayout()
self.setLayout(layout)
# splash screen frame
self.frame = QFrame()
layout.addWidget(self.frame)
# splash screen title
self.title_label = QLabel(self.frame)
self.title_label.setObjectName('title_label')
self.title_label.resize(690, 120)
self.title_label.move(0, 5) # x, y
self.title_label.setText('Splash Screen')
self.title_label.setAlignment(Qt.AlignCenter)
# splash screen title description
self.description_label = QLabel(self.frame)
self.description_label.resize(690, 40)
self.description_label.move(0, self.title_label.height())
self.description_label.setObjectName('desc_label')
self.description_label.setText('<b>Splash Screen PyQt-5</b>')
self.description_label.setAlignment(Qt.AlignCenter)
# splash screen pogressbar
self.progressBar = QProgressBar(self.frame)
self.progressBar.resize(self.width() - 200 - 10, 50)
self.progressBar.move(100, 180) # self.description_label.y()+130
self.progressBar.setAlignment(Qt.AlignCenter)
self.progressBar.setFormat('%p%')
self.progressBar.setTextVisible(True)
self.progressBar.setRange(0, self.n)
self.progressBar.setValue(20)
# spash screen loading label
self.loading_label = QLabel(self.frame)
self.loading_label.resize(self.width() - 10, 50)
self.loading_label.move(0, self.progressBar.y() + 70)
self.loading_label.setObjectName('loading_label')
self.loading_label.setAlignment(Qt.AlignCenter)
self.loading_label.setText('Loading...')
self.show()
def loading(self):
# set progressbar value
self.progressBar.setValue(self.counter)
# stop progress if counter
# is greater than n and
# display main window app
if self.counter >= self.n:
self.timer.stop()
'''
self.close()
MainWindow = QtWidgets.QMainWindow()
ui = WindowApp()
ui.setupUi(MainWindow)
MainWindow.show()
'''
self.ui = WindowApp()
self.ui.show()
self.close()
self.counter += 1
class WindowApp(QMainWindow):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1006, 654)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(10, 10, 981, 641))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(10)
self.label.setFont(font)
self.label.setText("")
self.label.setPixmap(QtGui.QPixmap("../pygui/Homescreen.png"))
self.label.setScaledContents(True)
self.label.setWordWrap(False)
self.label.setObjectName("label")
self.infoBtn = QtWidgets.QPushButton(self.centralwidget)
self.infoBtn.setGeometry(QtCore.QRect(120, 550, 181, 41))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(15)
self.infoBtn.setFont(font)
self.infoBtn.setStyleSheet("border-radius: 10px;\n"
"border-color: 2px solid gray;\n"
"background-color: rgb(255, 255, 255);")
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("icons/info_icon.png"),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.infoBtn.setIcon(icon)
self.infoBtn.setObjectName("infoBtn")
self.startBtn = QtWidgets.QPushButton(self.centralwidget)
self.startBtn.setGeometry(QtCore.QRect(310, 270, 431, 111))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(28)
self.startBtn.setFont(font)
self.startBtn.setStyleSheet("background-color: #305E6C;\n"
"color: white;\n"
"border-radius: 10px;\n"
"border: 2px solid white")
self.startBtn.setObjectName("startBtn")
self.contactsBtn = QtWidgets.QPushButton(self.centralwidget)
self.contactsBtn.setGeometry(QtCore.QRect(720, 30, 101, 101))
self.contactsBtn.setStyleSheet("\n"
"background-color: #121212;\n"
"border-radius: 50%;\n"
"border: 2px solid white;")
self.contactsBtn.setText("")
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap("icons/typcn_contacts.png"),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.contactsBtn.setIcon(icon1)
self.contactsBtn.setIconSize(QtCore.QSize(40, 40))
self.contactsBtn.setObjectName("contactsBtn")
self.dateBtn = QtWidgets.QPushButton(self.centralwidget)
self.dateBtn.setGeometry(QtCore.QRect(840, 30, 101, 101))
self.dateBtn.setStyleSheet("\n"
"background-color: #121212;\n"
"border-radius: 50%;\n"
"border: 2px solid white;")
self.dateBtn.setText("")
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap("icons/Group.png"),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.dateBtn.setIcon(icon2)
self.dateBtn.setIconSize(QtCore.QSize(40, 40))
self.dateBtn.setObjectName("dateBtn")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1006, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.infoBtn.clicked.connect(partial(self.show_popup))
self.dateBtn.clicked.connect(self.openDateWindow)
self.startBtn.clicked.connect(self.openDriveWindow)
self.contactsBtn.clicked.connect(self.openContactWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.infoBtn.setText(_translate("MainWindow", "About"))
self.startBtn.setText(_translate("MainWindow", "Driving Mode"))
def show_popup(self):
msg = QMessageBox()
msg.setWindowTitle('About Us')
msg.setText('Testing')
msg.setIcon(QMessageBox.Information)
x = msg.exec_()
def openDateWindow(self, MainWindow):
self.window = QtWidgets.QMainWindow()
self.ui = Ui_DateWindow()
self.ui.setupUi(self.window, MainWindow)
self.window.show()
MainWindow.hide()
def openDriveWindow(self, MainWindow):
self.window = QtWidgets.QMainWindow()
self.ui = Ui_DriveWindow()
self.ui.setupUi(self.window, MainWindow)
self.window.show()
MainWindow.hide()
def openContactWindow(self, MainWindow):
self.window = QtWidgets.QMainWindow()
self.ui = Ui_ContactWindow()
self.ui.setupUi(self.window, MainWindow)
self.window.show()
MainWindow.hide()
app = QApplication(sys.argv)
splash = SplashScreen()
#splash.show()
sys.exit(app.exec_())

QGraphicsScene. How do I draw an ellipse over a loaded image in pyqt5?

I have a QGraphicsView with a QGraphicsScene. On QGraphicsScene, I output the image using QGraphicsPixmapItem. And I would like to draw an ellipse over the image with my mouse.
I have that code now. And the ellipse is drawn on MainWindow.
What do I need to do to have the ellipse drawn on an image in QGraphicsView?
Code OFT_MainWindow
# OFT_MainWindow
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(862, 710)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)
self.graphicsView.setGeometry(QtCore.QRect(10, 90, 841, 571))
self.graphicsView.setMouseTracking(True)
self.graphicsView.setObjectName("graphicsView")
self.buttonBox = QtWidgets.QDialogButtonBox(self.centralwidget)
self.buttonBox.setGeometry(QtCore.QRect(360, 670, 81, 31))
font = QtGui.QFont()
font.setPointSize(10)
self.buttonBox.setFont(font)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(760, 10, 91, 31))
font = QtGui.QFont()
font.setPointSize(10)
self.pushButton.setFont(font)
self.pushButton.setObjectName("pushButton")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(10, 10, 731, 31))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit_2.setGeometry(QtCore.QRect(10, 670, 331, 31))
self.lineEdit_2.setObjectName("lineEdit_2")
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setGeometry(QtCore.QRect(10, 50, 841, 31))
font = QtGui.QFont()
font.setPointSize(10)
self.pushButton_2.setFont(font)
self.pushButton_2.setObjectName("pushButton_2")
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "Browse"))
self.pushButton_2.setText(_translate("MainWindow", "Highlight field area"))
Main code
import OFT_MainWindow
import sys
import os
import numpy as np
import cv2
from PIL import Image, ImageQt, ImageEnhance
from PyQt5 import QtWidgets
from PyQt5 import QtGui
from PyQt5 import QtCore
from PyQt5.QtCore import Qt, QPoint
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.Qt import Qt
def main():
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
class MainWindow(QtWidgets.QMainWindow, OFT_MainWindow.Ui_MainWindow, QtWidgets.QGraphicsView, QtWidgets.QGraphicsScene):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.pushButton.clicked.connect(self.browse_file)
self.pushButton_2.clicked.connect(self.imageFrame)
self.begin = QtCore.QPoint()
self.end = QtCore.QPoint()
self.show()
###################################################################################
def browse_file(self):
self.lineEdit.clear()
file = QtWidgets.QFileDialog.getOpenFileName(self, "Choose file")
file = str(file[0])
if file:
self.lineEdit.setText(file) # добавить путь в lineEdit
# cap = cv2.VideoCapture(file)
###################################################################################
def imageFrame(self):
file = self.lineEdit.text()
self.drawing = False
self.lastPoint = QPoint()
scene = QtWidgets.QGraphicsScene(self)
self.image = QPixmap(file)
item = QtWidgets.QGraphicsPixmapItem(self.image)
scene.addItem(item)
view = self.graphicsView.setScene(scene)
# self.show()
def paintEvent(self, event):
qp = QtGui.QPainter(self)
br = QtGui.QBrush(QtGui.QColor(0, 255, 0, 25))
qp.setBrush(br)
ellipse = qp.drawEllipse(QtCore.QRect(self.begin, self.end))
coord_a = self.begin
coord_a = str(coord_a)
coord_a = coord_a[20:][:-1]
coord_b = self.end
coord_b = str(coord_b)
coord_b = coord_b[20:][:-1]
coord = ('begin = ' + coord_a + ' end = ' + coord_b)
self.lineEdit_2.setText(coord)
def mousePressEvent(self, event):
self.begin = event.pos()
self.end = event.pos()
self.update()
def mouseMoveEvent(self, event):
self.end = event.pos()
self.update()
###################################################################################
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.aboutToQuit.connect(app.deleteLater)
sys.exit(app.exec_())
If you want to paint something on a QGraphicsView, you have to add QGraphicsItem to its scene, otherwise you're making almost useless to crete a QGraphicsView to begin with.
One possible solution is to install an event filter on the scene, listen for mouse button events and draw an ellipse (using QGraphicsEllipseItem) on the scene if the first click is done within the contents of a QGraphicsPixmapItem.
Note that another possibility is to subclass from QGraphicsPixmapItem and implement its mouse events instead. It all depends on what you're going to do and what you're going to need from your program.
class MainWindow(QtWidgets.QMainWindow, OFT_MainWindow.Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent)
# ...
self.ellipseItem = None
def imageFrame(self):
# ...
scene.installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == QtCore.QEvent.GraphicsSceneMousePress:
for item in self.graphicsView.scene().items(event.scenePos()):
if isinstance(item, QtWidgets.QGraphicsPixmapItem):
self.reference = item
self.ellipseItem = QtWidgets.QGraphicsEllipseItem(item)
self.ellipseItem.setBrush(QtGui.QColor(0, 255, 0, 25))
self.start = item.mapFromScene(event.scenePos())
elif event.type() == QtCore.QEvent.GraphicsSceneMouseMove and self.ellipseItem:
end = self.reference.mapFromScene(event.scenePos())
self.ellipseItem.setRect(QtCore.QRectF(self.start, end))
elif event.type() == QtCore.QEvent.GraphicsSceneMouseRelease and self.ellipseItem:
self.ellipseItem = None
return super().eventFilter(source, event)
Note that subclassing your Main window from all those classes (QtWidgets.QMainWindow, OFT_MainWindow.Ui_MainWindow, QtWidgets.QGraphicsView, QtWidgets.QGraphicsScene) is not only unnecessary and meaningless, but absolutely WRONG: multiple-inheritance subclassing should only be done when you know what you're inheriting from and why, otherwise, just don't. For Qt widgets that load from UI files, just subclass from the base widget class and the Ui.

Trouble adding click event to PyQt5 button, no connect after clicked [duplicate]

This question already has answers here:
Calling a function upon button press
(3 answers)
Closed 3 years ago.
fairly new to PyQt and Python in general. I am having trouble applying a click event to a button in PyQt5. I am trying to add functionality to all the buttons I have, although it seems I am missing some initial setup to allow it to work. Looking through the documentation...
pushButton.clicked.connect("Do some action")
..should enable the click functionality on the targeted button.
I do not currently have the connect option available after the pushbutton.connect call.
I assume I am missing some setup in the class.
from PyQt5 import QtCore, QtGui, QtWidgets
import cheekycheeky
import datetime
import ntplib
import time
class ContLCDClock(QtWidgets.QWidget,):
def __init__(self, parent = None):
QtWidgets.QWidget.__init__(self, parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.updateLCD1)
self.timer.start(1000)
# self.timer2 = QtCore.QTimer()
# self.timer2.timeout.connect(self.updateLCD2)
# self.timer2.start(4000)
# self.time_format = "%H:%M:%S"
# self.client = ntplib.NTPClient()
# self.response = self.client.request('pool.ntp.org')
# self.clock = time.strftime(self.time_format, time.localtime(self.response.tx_time))
def updateLCD1(self):
self.currentTime = QtCore.QTime.currentTime()
self.strCurrentTime = self.currentTime.toString('hh:mm:ss')
self.ui.lcdNumber.display(self.strCurrentTime)
# def updateLCD2(self):
# self.time_format = "%H:%M:%S"
# self.client = ntplib.NTPClient()
# self.response = self.client.request('pool.ntp.org')
# self.clock = time.strftime(self.time_format, time.localtime(self.response.tx_time))
# self.ui.lcdNumber_2.display(self.clock)
class Ui_Form(object) :
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(335, 157)
self.pushButton_7 = QtWidgets.QPushButton(Form)
self.pushButton_7.setGeometry(QtCore.QRect(50, 120, 31, 23))
self.pushButton_7.setObjectName("pushButton_7")
self.pushButton_7.clicked.connect(print('I am working')) # This does not work
self.pushButton_9 = QtWidgets.QPushButton(Form)
self.pushButton_9.setGeometry(QtCore.QRect(90, 120, 31, 23))
self.pushButton_9.setObjectName("pushButton_9")
self.pushButton_6 = QtWidgets.QPushButton(Form)
self.pushButton_6.setGeometry(QtCore.QRect(210, 120, 31, 23))
self.pushButton_6.setObjectName("pushButton_6")
self.pushButton_3 = QtWidgets.QPushButton(Form)
self.pushButton_3.setGeometry(QtCore.QRect(290, 120, 31, 23))
self.pushButton_3.setObjectName("pushButton_3")
self.label = QtWidgets.QLabel(Form)
self.label.setGeometry(QtCore.QRect(9, 16, 80, 19))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
font.setBold(True)
font.setWeight(75)
self.label.setFont(font)
self.label.setObjectName("label")
self.pushButton_8 = QtWidgets.QPushButton(Form)
self.pushButton_8.setGeometry(QtCore.QRect(9, 120, 31, 23))
self.pushButton_8.setObjectName("pushButton_8")
self.pushButton_4 = QtWidgets.QPushButton(Form)
self.pushButton_4.setGeometry(QtCore.QRect(130, 120, 71, 23))
self.pushButton_4.setObjectName("pushButton_4")
self.pushButton_5 = QtWidgets.QPushButton(Form)
self.pushButton_5.setGeometry(QtCore.QRect(250, 120, 31, 23))
self.pushButton_5.setObjectName("pushButton_5")
self.lcdNumber_2 = QtWidgets.QLCDNumber(Form)
self.lcdNumber_2.setGeometry(QtCore.QRect(145, 9, 171, 31))
self.lcdNumber_2.setObjectName("lcdNumber_2")
self.lcdNumber_2.setDigitCount(11)
self.lcdNumber = QtWidgets.QLCDNumber(Form)
self.lcdNumber.setGeometry(QtCore.QRect(145, 59, 171, 31))
self.lcdNumber.setObjectName("lcdNumber")
self.lcdNumber.setDigitCount(8)
self.label_2 = QtWidgets.QLabel(Form)
self.label_2.setGeometry(QtCore.QRect(9, 67, 105, 19))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
font.setBold(True)
font.setWeight(75)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Cheeky Timer"))
self.pushButton_7.setText(_translate("Form", "-.5"))
self.pushButton_9.setText(_translate("Form", "-.1"))
self.pushButton_6.setText(_translate("Form", "+.1"))
self.pushButton_3.setText(_translate("Form", "+1"))
self.label.setText(_translate("Form", "NTP Time:"))
self.pushButton_8.setText(_translate("Form", "-1"))
self.pushButton_4.setText(_translate("Form", "Reset Time"))
self.pushButton_5.setText(_translate("Form", "+.5"))
self.label_2.setText(_translate("Form", "Current Time:"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
c = ContLCDClock()
c.show()
sys.exit(app.exec_())
Thank you in advance for any help, I hope I have been clear enough.
I think it may be because your input is incorrect, an example piece:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
class App(QWidget):
def __init__(self):
super().__init__()
self.title = 'PyQt5 button - pythonspot.com'
self.left = 10
self.top = 10
self.width = 320
self.height = 200
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
button = QPushButton('PyQt5 button', self)
button.setToolTip('This is an example button')
button.move(100,70)
button.clicked.connect(self.on_click)
self.show()
#pyqtSlot()
def on_click(self):
print('PyQt5 button click')
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
Here a function self.on_click is passed. In your example, you pass print('I am working'), which returns a None. You could fix this for instance like this:
from PyQt5 import QtCore, QtGui, QtWidgets
import cheekycheeky
import datetime
import ntplib
import time
class ContLCDClock(QtWidgets.QWidget,):
def __init__(self, parent = None):
QtWidgets.QWidget.__init__(self, parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.updateLCD1)
self.timer.start(1000)
# self.timer2 = QtCore.QTimer()
# self.timer2.timeout.connect(self.updateLCD2)
# self.timer2.start(4000)
# self.time_format = "%H:%M:%S"
# self.client = ntplib.NTPClient()
# self.response = self.client.request('pool.ntp.org')
# self.clock = time.strftime(self.time_format, time.localtime(self.response.tx_time))
def updateLCD1(self):
self.currentTime = QtCore.QTime.currentTime()
self.strCurrentTime = self.currentTime.toString('hh:mm:ss')
self.ui.lcdNumber.display(self.strCurrentTime)
# def updateLCD2(self):
# self.time_format = "%H:%M:%S"
# self.client = ntplib.NTPClient()
# self.response = self.client.request('pool.ntp.org')
# self.clock = time.strftime(self.time_format, time.localtime(self.response.tx_time))
# self.ui.lcdNumber_2.display(self.clock)
class Ui_Form(object) :
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(335, 157)
self.pushButton_7 = QtWidgets.QPushButton(Form)
self.pushButton_7.setGeometry(QtCore.QRect(50, 120, 31, 23))
self.pushButton_7.setObjectName("pushButton_7")
self.pushButton_7.clicked.connect(self.i_am_working)
self.pushButton_9 = QtWidgets.QPushButton(Form)
self.pushButton_9.setGeometry(QtCore.QRect(90, 120, 31, 23))
self.pushButton_9.setObjectName("pushButton_9")
self.pushButton_6 = QtWidgets.QPushButton(Form)
self.pushButton_6.setGeometry(QtCore.QRect(210, 120, 31, 23))
self.pushButton_6.setObjectName("pushButton_6")
self.pushButton_3 = QtWidgets.QPushButton(Form)
self.pushButton_3.setGeometry(QtCore.QRect(290, 120, 31, 23))
self.pushButton_3.setObjectName("pushButton_3")
self.label = QtWidgets.QLabel(Form)
self.label.setGeometry(QtCore.QRect(9, 16, 80, 19))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
font.setBold(True)
font.setWeight(75)
self.label.setFont(font)
self.label.setObjectName("label")
self.pushButton_8 = QtWidgets.QPushButton(Form)
self.pushButton_8.setGeometry(QtCore.QRect(9, 120, 31, 23))
self.pushButton_8.setObjectName("pushButton_8")
self.pushButton_4 = QtWidgets.QPushButton(Form)
self.pushButton_4.setGeometry(QtCore.QRect(130, 120, 71, 23))
self.pushButton_4.setObjectName("pushButton_4")
self.pushButton_5 = QtWidgets.QPushButton(Form)
self.pushButton_5.setGeometry(QtCore.QRect(250, 120, 31, 23))
self.pushButton_5.setObjectName("pushButton_5")
self.lcdNumber_2 = QtWidgets.QLCDNumber(Form)
self.lcdNumber_2.setGeometry(QtCore.QRect(145, 9, 171, 31))
self.lcdNumber_2.setObjectName("lcdNumber_2")
self.lcdNumber_2.setDigitCount(11)
self.lcdNumber = QtWidgets.QLCDNumber(Form)
self.lcdNumber.setGeometry(QtCore.QRect(145, 59, 171, 31))
self.lcdNumber.setObjectName("lcdNumber")
self.lcdNumber.setDigitCount(8)
self.label_2 = QtWidgets.QLabel(Form)
self.label_2.setGeometry(QtCore.QRect(9, 67, 105, 19))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
font.setBold(True)
font.setWeight(75)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Cheeky Timer"))
self.pushButton_7.setText(_translate("Form", "-.5"))
self.pushButton_9.setText(_translate("Form", "-.1"))
self.pushButton_6.setText(_translate("Form", "+.1"))
self.pushButton_3.setText(_translate("Form", "+1"))
self.label.setText(_translate("Form", "NTP Time:"))
self.pushButton_8.setText(_translate("Form", "-1"))
self.pushButton_4.setText(_translate("Form", "Reset Time"))
self.pushButton_5.setText(_translate("Form", "+.5"))
self.label_2.setText(_translate("Form", "Current Time:"))
def i_am_working(self):
print('I am working')
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
c = ContLCDClock()
c.show()
sys.exit(app.exec_())

QObject::setParent: Cannot set parent, new parent is in a different thread in Python

I am facing a problem with the GUI I developed using PyQt5.
The app tries to update the value of a progress bar of the window from a different thread (QThreadPool()). When it tries to update the progress bar, the python gives a warning as below:
QObject::setParent: Cannot set parent, new parent is in a different thread
This doesn't affect the app to certain extent but after a while the app crashes with the following error message.
QBackingStore::endPaint() called with active painter on backingstore paint device
Could anyone help me to get rid of the first warning? I guess that will solve the problem.
I will post a minimal example of the code.
main.py
import sys
from PyQt5.QtCore import *
from PyQt5 import QtCore, QtGui, QtWidgets
import thread_for_audio_record
import time
class FW(object):
def __init__(self):
self.threadpool = QThreadPool()
def f_w(self, window):
self.window = window
self.window.setObjectName("Test")
self.window.resize(1054, 700)
self.window.setStyleSheet("background-color: rgb(180, 180, 180);")
self.central_widget = QtWidgets.QWidget(self.window)
self.central_widget.setObjectName("centralwidget")
self.horizontal_layout = QtWidgets.QHBoxLayout(self.central_widget)
self.horizontal_layout.setObjectName("horizontalLayout")
spacer_item = QtWidgets.QSpacerItem(129, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontal_layout.addItem(spacer_item)
self.vertical_layout = QtWidgets.QVBoxLayout()
self.vertical_layout.setObjectName("verticalLayout")
spacer_item_1 = QtWidgets.QSpacerItem(128, 13, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.vertical_layout.addItem(spacer_item_1)
self.label_utterance = QtWidgets.QLabel(self.central_widget)
font = QtGui.QFont()
font.setPointSize(15)
font.setBold(True)
font.setBold(True)
font.setWeight(75)
self.label_utterance.setFont(font)
self.label_utterance.setAlignment(QtCore.Qt.AlignCenter)
self.label_utterance.setObjectName("label_utterance")
self.vertical_layout.addWidget(self.label_utterance)
self.text_edit_utterance = QtWidgets.QTextEdit(self.central_widget)
self.text_edit_utterance.setStyleSheet("background-color: rgb(255, 255, 255);")
self.text_edit_utterance.setObjectName("text_edit_utterance")
self.text_edit_utterance.setReadOnly(True)
self.text_edit_utterance.setFont(font)
self.vertical_layout.addWidget(self.text_edit_utterance)
self.line_edit_message_for_user = QtWidgets.QLineEdit(self.central_widget)
self.line_edit_message_for_user.setStyleSheet("background-color: rgb(255, 255, 255);")
self.line_edit_message_for_user.setObjectName("lineEdit")
self.progressBar = QtWidgets.QProgressBar(self.central_widget)
self.progressBar.setProperty("value", 0)
self.progressBar.setObjectName("progressBar")
self.vertical_layout.addWidget(self.progressBar)
self.vertical_layout.addWidget(self.line_edit_message_for_user)
self.push_button_start_recording = QtWidgets.QPushButton(self.central_widget)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.push_button_start_recording.setFont(font)
self.push_button_start_recording.setStyleSheet("background-color: rgb(85, 170, 0);")
self.push_button_start_recording.setObjectName("pushButton_start_
recording")
self.push_button_start_recording.clicked.connect(self.start_button_
func)
self.vertical_layout.addWidget(self.push_button_start_recording)
self.push_button_end_recording = QtWidgets.QPushButton(self.central_widget)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.push_button_end_recording.setFont(font)
self.push_button_end_recording.setStyleSheet("background-color: rgb(182, 0, 0);")
self.push_button_end_recording.setObjectName("pushButton_end_
recording")
self.vertical_layout.addWidget(self.push_button_end_recording)
self.label_status = QtWidgets.QLabel(self.central_widget)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_status.setFont(font)
self.label_status.setObjectName("label_status")
self.vertical_layout.addWidget(self.label_status)
self.text_edit_status = QtWidgets.QTextEdit(self.central_widget)
self.text_edit_status.setStyleSheet("background-color: rgb(255, 255, 255);")
self.text_edit_status.setObjectName("textEdit_status")
self.text_edit_status.setReadOnly(True)
self.vertical_layout.addWidget(self.text_edit_status)
self.push_button_record_again = QtWidgets.QPushButton(self.central_widget)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.push_button_record_again.setFont(font)
self.push_button_record_again.setStyleSheet("background-color: rgb(255, 255, 127);")
self.push_button_record_again.setObjectName("pushButton_record_
again")
self.vertical_layout.addWidget(self.push_button_record_again)
self.push_button_next_utterance = QtWidgets.QPushButton(self.central_widget)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.push_button_next_utterance.setFont(font)
self.push_button_next_utterance.setStyleSheet("background-color: rgb(85, 170, 0);")
self.push_button_next_utterance.setObjectName("pushButton_next_
utterance")
self.vertical_layout.addWidget(self.push_button_next_utterance)
spacer_item_2 = QtWidgets.QSpacerItem(128, 13, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.vertical_layout.addItem(spacer_item_2)
self.horizontal_layout.addLayout(self.vertical_layout)
spacer_item_3 = QtWidgets.QSpacerItem(128, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontal_layout.addItem(spacer_item_3)
self.window.setCentralWidget(self.central_widget)
self.menubar = QtWidgets.QMenuBar(self.window)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1054, 21))
self.menubar.setObjectName("menubar")
self.window.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(self.window)
self.statusbar.setObjectName("statusbar")
self.window.setStatusBar(self.statusbar)
self.retranslate_ui(self.window)
QtCore.QMetaObject.connectSlotsByName(self.window)
def retranslate_ui(self, window):
_translate = QtCore.QCoreApplication.translate
window.setWindowTitle(_translate("Utterance Recording", "Test"))
self.label_utterance.setText(_translate("Utterance Recording", "Test"))
self.line_edit_message_for_user.setText(_translate("Utterance Recording", "Test."))
self.text_edit_utterance.setText(_translate("utterance_parsing", ('Test')))
self.push_button_start_recording.setText(_translate("Utterance Recording", "Start Recording"))
self.push_button_end_recording.setText(_translate("Utterance Recording", "End Recording"))
self.label_status.setText(_translate("Utterance Recording", "Test"))
self.push_button_record_again.setText(_translate("Utterance Recording", "Test"))
self.push_button_next_utterance.setText(_translate("Utterance Recording", "Test"))
def inside_thread(self):
percentage = 0
while percentage < 120:
percentage = percentage + 20
time.sleep(0.2)
self.progressBar.setValue(percentage)
def start_button_func(self):
self.worker = thread_for_audio_record.Worker(self.inside_thread)
self.threadpool.start(self.worker)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
utterance_parsing_window = QtWidgets.QMainWindow()
utterance_parsing = FW()
utterance_parsing.f_w(utterance_parsing_window)
utterance_parsing_window.show()
sys.exit(app.exec_())
thread_for_audio_record.py
import os
from PyQt5.QtCore import *
class Worker(QRunnable):
def __init__(self, fn):
super(Worker, self).__init__()
self.fn = fn
self.originating_PID = os.getpid()
self._running = True
#pyqtSlot()
def run(self):
self.fn()
Click the Start Recording button and you will see the progress bar getting updated. But the warning message is given cause the update is from a different thread.
First, do not modify the code generated by Qt Designer as PyQt recommends, instead create another class that inherits from the appropriate widget and use the initial class as an interface.
Going to the point, Qt does not allow the GUI to be updated from another thread directly, in your case the setValue of the QProgressBar is called in the secondary thread causing the painting to be made in the secuandario thread so Qt complains that it is not guaranteed operation (for example in your case it does not generate problems apparently but Qt does not guarantee that this always happens). The update of the GUI from other threads must be indirectly, which can be through signals, QEvent, QMetaObject::invokeMethod, etc. In this case I will use the signals:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
import thread_for_audio_record
import time
class FW(object):
def f_w(self, window):
self.window = window
self.window.setObjectName("Test")
self.window.resize(1054, 700)
self.window.setStyleSheet("background-color: rgb(180, 180, 180);")
self.central_widget = QtWidgets.QWidget(self.window)
self.central_widget.setObjectName("centralwidget")
self.horizontal_layout = QtWidgets.QHBoxLayout(self.central_widget)
self.horizontal_layout.setObjectName("horizontalLayout")
spacer_item = QtWidgets.QSpacerItem(129, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontal_layout.addItem(spacer_item)
self.vertical_layout = QtWidgets.QVBoxLayout()
self.vertical_layout.setObjectName("verticalLayout")
spacer_item_1 = QtWidgets.QSpacerItem(128, 13, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.vertical_layout.addItem(spacer_item_1)
self.label_utterance = QtWidgets.QLabel(self.central_widget)
font = QtGui.QFont()
font.setPointSize(15)
font.setBold(True)
font.setBold(True)
font.setWeight(75)
self.label_utterance.setFont(font)
self.label_utterance.setAlignment(QtCore.Qt.AlignCenter)
self.label_utterance.setObjectName("label_utterance")
self.vertical_layout.addWidget(self.label_utterance)
self.text_edit_utterance = QtWidgets.QTextEdit(self.central_widget)
self.text_edit_utterance.setStyleSheet("background-color: rgb(255, 255, 255);")
self.text_edit_utterance.setObjectName("text_edit_utterance")
self.text_edit_utterance.setReadOnly(True)
self.text_edit_utterance.setFont(font)
self.vertical_layout.addWidget(self.text_edit_utterance)
self.line_edit_message_for_user = QtWidgets.QLineEdit(self.central_widget)
self.line_edit_message_for_user.setStyleSheet("background-color: rgb(255, 255, 255);")
self.line_edit_message_for_user.setObjectName("lineEdit")
self.progressBar = QtWidgets.QProgressBar(self.central_widget)
self.progressBar.setProperty("value", 0)
self.progressBar.setObjectName("progressBar")
self.vertical_layout.addWidget(self.progressBar)
self.vertical_layout.addWidget(self.line_edit_message_for_user)
self.push_button_start_recording = QtWidgets.QPushButton(self.central_widget)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.push_button_start_recording.setFont(font)
self.push_button_start_recording.setStyleSheet("background-color: rgb(85, 170, 0);")
self.push_button_start_recording.setObjectName("pushButton_start_ recording")
self.vertical_layout.addWidget(self.push_button_start_recording)
self.push_button_end_recording = QtWidgets.QPushButton(self.central_widget)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.push_button_end_recording.setFont(font)
self.push_button_end_recording.setStyleSheet("background-color: rgb(182, 0, 0);")
self.push_button_end_recording.setObjectName("pushButton_end_recording")
self.vertical_layout.addWidget(self.push_button_end_recording)
self.label_status = QtWidgets.QLabel(self.central_widget)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_status.setFont(font)
self.label_status.setObjectName("label_status")
self.vertical_layout.addWidget(self.label_status)
self.text_edit_status = QtWidgets.QTextEdit(self.central_widget)
self.text_edit_status.setStyleSheet("background-color: rgb(255, 255, 255);")
self.text_edit_status.setObjectName("textEdit_status")
self.text_edit_status.setReadOnly(True)
self.vertical_layout.addWidget(self.text_edit_status)
self.push_button_record_again = QtWidgets.QPushButton(self.central_widget)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.push_button_record_again.setFont(font)
self.push_button_record_again.setStyleSheet("background-color: rgb(255, 255, 127);")
self.push_button_record_again.setObjectName("pushButton_record_again")
self.vertical_layout.addWidget(self.push_button_record_again)
self.push_button_next_utterance = QtWidgets.QPushButton(self.central_widget)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.push_button_next_utterance.setFont(font)
self.push_button_next_utterance.setStyleSheet("background-color: rgb(85, 170, 0);")
self.push_button_next_utterance.setObjectName("pushButton_next_utterance")
self.vertical_layout.addWidget(self.push_button_next_utterance)
spacer_item_2 = QtWidgets.QSpacerItem(128, 13, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.vertical_layout.addItem(spacer_item_2)
self.horizontal_layout.addLayout(self.vertical_layout)
spacer_item_3 = QtWidgets.QSpacerItem(128, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontal_layout.addItem(spacer_item_3)
self.window.setCentralWidget(self.central_widget)
self.menubar = QtWidgets.QMenuBar(self.window)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1054, 21))
self.menubar.setObjectName("menubar")
self.window.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(self.window)
self.statusbar.setObjectName("statusbar")
self.window.setStatusBar(self.statusbar)
self.retranslate_ui(self.window)
QtCore.QMetaObject.connectSlotsByName(self.window)
def retranslate_ui(self, window):
_translate = QtCore.QCoreApplication.translate
window.setWindowTitle(_translate("Utterance Recording", "Altran Audio Manager"))
self.label_utterance.setText(_translate("Utterance Recording", "Test"))
self.line_edit_message_for_user.setText(_translate("Utterance Recording", "Test."))
self.text_edit_utterance.setText(_translate("utterance_parsing", ('Test')))
self.push_button_start_recording.setText(_translate("Utterance Recording", "Start Recording"))
self.push_button_end_recording.setText(_translate("Utterance Recording", "End Recording"))
self.label_status.setText(_translate("Utterance Recording", "Test"))
self.push_button_record_again.setText(_translate("Utterance Recording", "Test"))
self.push_button_next_utterance.setText(_translate("Utterance Recording", "Test"))
class MainWindow(QtWidgets.QMainWindow, FW):
progressChanged = QtCore.pyqtSignal(int)
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.threadpool = QtCore.QThreadPool()
self.f_w(self)
self.push_button_start_recording.clicked.connect(self.start_button_func)
self.progressChanged.connect(self.progressBar.setValue)
def inside_thread(self):
percentage = 0
while percentage < 120:
percentage = percentage + 20
time.sleep(0.2)
self.progressChanged.emit(percentage)
def start_button_func(self):
self.worker = thread_for_audio_record.Worker(self.inside_thread)
self.threadpool.start(self.worker)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())

Line between widgets drawn in wrong position on graphics view

I'm drawing a line between two widgets (two push buttons) into a graphics view with their positions as reference. But the line is drawn in a wrong place.
I tried using functions like mapToGlobal or mapToParent with different results, but it's still wrong. In the same class I have another method that draws lines with the mouse, and it works ok. I was taking it like a reference, but it seems that the events position has a different coordinate system. I don't know why this is happening.
The buttons and the graphics view are inside a Widget, which is also inside a window.
Here it is the class:
from PyQt4 import QtGui, QtCore
class WiringGraphicsView(QtGui.QGraphicsView):
def __init__(self, parent):
QtGui.QGraphicsView.__init__(self, parent)
self.setScene(QtGui.QGraphicsScene(self))
#self.setSceneRect(QtCore.QRectF(self.viewport().rect()))
def mousePressEvent(self, event):
self._start = event.pos()
def mouseReleaseEvent(self, event):
start = QtCore.QPointF(self.mapToScene(self._start))
end = QtCore.QPointF(self.mapToScene(event.pos()))
brush = QtGui.QBrush(QtGui.QColor(255, 0, 0) )
pen = QtGui.QPen(brush, 2)
line = QtGui.QGraphicsLineItem(QtCore.QLineF(start, end))
line.setPen(pen)
self.scene().addItem( line )
def paintWire(self, start_widget, end_widget):
start_position = QtCore.QPointF(self.mapToScene(start_widget.pos()))
end_position = QtCore.QPointF(self.mapToScene(end_widget.pos()))
brush = QtGui.QBrush(QtGui.QColor(255, 0, 0) )
pen = QtGui.QPen(brush, 2)
line = QtGui.QGraphicsLineItem(QtCore.QLineF(start_position, end_position))
line.setPen(pen)
self.scene().addItem( line )
UPDATE: At this point I've tried several things: Since the buttons were contained in a QWidget object, I take them out from there. I put them in a GroupBox instead. Also tried without containers. I don't get satisfactory results. Honestly I don't know how to do this properly considering that I'm using Qt designer and creating class files for "promoted" widgets (in this case is the GraphicsView) and set up some properties using the UpdateUi method in the main file
UPDATE 2: Here it is the file where the application is loaded:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import ui_wolfsonmixerwindow
class WolfsonMixerWindow(QMainWindow, ui_wolfsonmixerwindow.Ui_WolfsonMixerWindow):
def __init__(self, parent=None):
super(WolfsonMixerWindow, self).__init__(parent)
self.setupUi(self)
self.updateUi()
def updateUi(self):
#self.btn_AIF1RX1.setText("Hola")
menu_plugin = QMenu()
menu_unplug = QMenu()
menu_plugin.addAction('Action 1', self.plugin )
self.btn_AIF1RX1_2.setMenu(menu_plugin)
self.btn_AIF1TX1_5.setAllowDrag(False)
self.btn_AIF1TX1_5.setMenu(menu_unplug)
start = self.btn_AIF1RX1_2
end = self.btn_AIF1TX1_5
#self.graphicsView.scene().addWidget(self.btn_AIF1RX1_2)
#self.graphicsView.scene().addWidget(self.btn_AIF1TX1_5)
#self.graphicsView.setWidgets(start, end)
#HERE I CALL THE PAINTWIRE METHOD
self.graphicsView.paintWire(start, end)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
form = WolfsonMixerWindow()
form.show()
app.exec_()
And the uic file:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui_wolfsonmixerwindow.ui'
#
# Created: Thu Feb 19 21:51:35 2015
# by: PyQt4 UI code generator 4.11.3
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_WolfsonMixerWindow(object):
def setupUi(self, WolfsonMixerWindow):
WolfsonMixerWindow.setObjectName(_fromUtf8("WolfsonMixerWindow"))
WolfsonMixerWindow.resize(562, 480)
self.centralwidget = QtGui.QWidget(WolfsonMixerWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.gridLayoutWidget = QtGui.QWidget(self.centralwidget)
self.gridLayoutWidget.setGeometry(QtCore.QRect(200, 10, 241, 101))
self.gridLayoutWidget.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.gridLayoutWidget.setObjectName(_fromUtf8("gridLayoutWidget"))
self.gridLayout = QtGui.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setSizeConstraint(QtGui.QLayout.SetMaximumSize)
self.gridLayout.setMargin(0)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.QHBox_Playback = QtGui.QHBoxLayout()
self.QHBox_Playback.setObjectName(_fromUtf8("QHBox_Playback"))
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.label_2 = QtGui.QLabel(self.gridLayoutWidget)
self.label_2.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.label_2.setAlignment(QtCore.Qt.AlignCenter)
self.label_2.setObjectName(_fromUtf8("label_2"))
self.verticalLayout.addWidget(self.label_2)
self.label = QtGui.QLabel(self.gridLayoutWidget)
self.label.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName(_fromUtf8("label"))
self.verticalLayout.addWidget(self.label)
self.btn_AIF1RX1 = DragButton(self.gridLayoutWidget)
self.btn_AIF1RX1.setBaseSize(QtCore.QSize(0, 0))
self.btn_AIF1RX1.setMouseTracking(True)
self.btn_AIF1RX1.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1RX1.setText(_fromUtf8(""))
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/audio-input-line.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btn_AIF1RX1.setIcon(icon)
self.btn_AIF1RX1.setAutoDefault(False)
self.btn_AIF1RX1.setDefault(False)
self.btn_AIF1RX1.setFlat(True)
self.btn_AIF1RX1.setObjectName(_fromUtf8("btn_AIF1RX1"))
self.verticalLayout.addWidget(self.btn_AIF1RX1)
self.QHBox_Playback.addLayout(self.verticalLayout)
self.verticalLayout_2 = QtGui.QVBoxLayout()
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
self.label_3 = QtGui.QLabel(self.gridLayoutWidget)
self.label_3.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.label_3.setAlignment(QtCore.Qt.AlignCenter)
self.label_3.setObjectName(_fromUtf8("label_3"))
self.verticalLayout_2.addWidget(self.label_3)
self.label_4 = QtGui.QLabel(self.gridLayoutWidget)
self.label_4.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.label_4.setAlignment(QtCore.Qt.AlignCenter)
self.label_4.setObjectName(_fromUtf8("label_4"))
self.verticalLayout_2.addWidget(self.label_4)
self.btn_AIF1RX2 = QtGui.QPushButton(self.gridLayoutWidget)
self.btn_AIF1RX2.setBaseSize(QtCore.QSize(0, 0))
self.btn_AIF1RX2.setMouseTracking(True)
self.btn_AIF1RX2.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1RX2.setText(_fromUtf8(""))
self.btn_AIF1RX2.setIcon(icon)
self.btn_AIF1RX2.setAutoDefault(False)
self.btn_AIF1RX2.setDefault(False)
self.btn_AIF1RX2.setFlat(True)
self.btn_AIF1RX2.setObjectName(_fromUtf8("btn_AIF1RX2"))
self.verticalLayout_2.addWidget(self.btn_AIF1RX2)
self.QHBox_Playback.addLayout(self.verticalLayout_2)
self.gridLayout.addLayout(self.QHBox_Playback, 1, 0, 1, 1)
self.horizontalLayout_3 = QtGui.QHBoxLayout()
self.horizontalLayout_3.setSizeConstraint(QtGui.QLayout.SetDefaultConstraint)
self.horizontalLayout_3.setContentsMargins(-1, -1, 0, -1)
self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3"))
self.verticalLayout_3 = QtGui.QVBoxLayout()
self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3"))
self.label_6 = QtGui.QLabel(self.gridLayoutWidget)
self.label_6.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.label_6.setAlignment(QtCore.Qt.AlignCenter)
self.label_6.setObjectName(_fromUtf8("label_6"))
self.verticalLayout_3.addWidget(self.label_6)
self.label_5 = QtGui.QLabel(self.gridLayoutWidget)
self.label_5.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.label_5.setAlignment(QtCore.Qt.AlignCenter)
self.label_5.setObjectName(_fromUtf8("label_5"))
self.verticalLayout_3.addWidget(self.label_5)
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setSpacing(0)
self.horizontalLayout.setSizeConstraint(QtGui.QLayout.SetDefaultConstraint)
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.btn_AIF1TX1_1 = QtGui.QPushButton(self.gridLayoutWidget)
self.btn_AIF1TX1_1.setMouseTracking(False)
self.btn_AIF1TX1_1.setFocusPolicy(QtCore.Qt.StrongFocus)
self.btn_AIF1TX1_1.setAcceptDrops(True)
self.btn_AIF1TX1_1.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1TX1_1.setText(_fromUtf8(""))
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/input_small.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btn_AIF1TX1_1.setIcon(icon1)
self.btn_AIF1TX1_1.setFlat(True)
self.btn_AIF1TX1_1.setObjectName(_fromUtf8("btn_AIF1TX1_1"))
self.horizontalLayout.addWidget(self.btn_AIF1TX1_1)
self.btn_AIF1TX1_2 = QtGui.QPushButton(self.gridLayoutWidget)
self.btn_AIF1TX1_2.setAcceptDrops(True)
self.btn_AIF1TX1_2.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1TX1_2.setText(_fromUtf8(""))
self.btn_AIF1TX1_2.setIcon(icon1)
self.btn_AIF1TX1_2.setFlat(True)
self.btn_AIF1TX1_2.setObjectName(_fromUtf8("btn_AIF1TX1_2"))
self.horizontalLayout.addWidget(self.btn_AIF1TX1_2)
self.btn_AIF1TX1_3 = QtGui.QPushButton(self.gridLayoutWidget)
self.btn_AIF1TX1_3.setAcceptDrops(True)
self.btn_AIF1TX1_3.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1TX1_3.setText(_fromUtf8(""))
self.btn_AIF1TX1_3.setIcon(icon1)
self.btn_AIF1TX1_3.setFlat(True)
self.btn_AIF1TX1_3.setObjectName(_fromUtf8("btn_AIF1TX1_3"))
self.horizontalLayout.addWidget(self.btn_AIF1TX1_3)
self.btn_AIF1TX1_4 = QtGui.QPushButton(self.gridLayoutWidget)
self.btn_AIF1TX1_4.setAcceptDrops(True)
self.btn_AIF1TX1_4.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1TX1_4.setText(_fromUtf8(""))
self.btn_AIF1TX1_4.setIcon(icon1)
self.btn_AIF1TX1_4.setFlat(True)
self.btn_AIF1TX1_4.setObjectName(_fromUtf8("btn_AIF1TX1_4"))
self.horizontalLayout.addWidget(self.btn_AIF1TX1_4)
self.verticalLayout_3.addLayout(self.horizontalLayout)
self.horizontalLayout_3.addLayout(self.verticalLayout_3)
self.verticalLayout_4 = QtGui.QVBoxLayout()
self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4"))
self.label_7 = QtGui.QLabel(self.gridLayoutWidget)
self.label_7.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.label_7.setAlignment(QtCore.Qt.AlignCenter)
self.label_7.setObjectName(_fromUtf8("label_7"))
self.verticalLayout_4.addWidget(self.label_7)
self.label_8 = QtGui.QLabel(self.gridLayoutWidget)
self.label_8.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.label_8.setAlignment(QtCore.Qt.AlignCenter)
self.label_8.setObjectName(_fromUtf8("label_8"))
self.verticalLayout_4.addWidget(self.label_8)
self.horizontalLayout_2 = QtGui.QHBoxLayout()
self.horizontalLayout_2.setSpacing(1)
self.horizontalLayout_2.setSizeConstraint(QtGui.QLayout.SetDefaultConstraint)
self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2"))
self.btn_AIF1TX2_1 = QtGui.QPushButton(self.gridLayoutWidget)
self.btn_AIF1TX2_1.setAcceptDrops(True)
self.btn_AIF1TX2_1.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1TX2_1.setText(_fromUtf8(""))
self.btn_AIF1TX2_1.setIcon(icon1)
self.btn_AIF1TX2_1.setFlat(True)
self.btn_AIF1TX2_1.setObjectName(_fromUtf8("btn_AIF1TX2_1"))
self.horizontalLayout_2.addWidget(self.btn_AIF1TX2_1)
self.btn_AIF1TX2_2 = QtGui.QPushButton(self.gridLayoutWidget)
self.btn_AIF1TX2_2.setAcceptDrops(True)
self.btn_AIF1TX2_2.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1TX2_2.setText(_fromUtf8(""))
self.btn_AIF1TX2_2.setIcon(icon1)
self.btn_AIF1TX2_2.setFlat(True)
self.btn_AIF1TX2_2.setObjectName(_fromUtf8("btn_AIF1TX2_2"))
self.horizontalLayout_2.addWidget(self.btn_AIF1TX2_2)
self.btn_AIF1TX2_3 = QtGui.QPushButton(self.gridLayoutWidget)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.btn_AIF1TX2_3.sizePolicy().hasHeightForWidth())
self.btn_AIF1TX2_3.setSizePolicy(sizePolicy)
self.btn_AIF1TX2_3.setAcceptDrops(True)
self.btn_AIF1TX2_3.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1TX2_3.setText(_fromUtf8(""))
self.btn_AIF1TX2_3.setIcon(icon1)
self.btn_AIF1TX2_3.setFlat(True)
self.btn_AIF1TX2_3.setObjectName(_fromUtf8("btn_AIF1TX2_3"))
self.horizontalLayout_2.addWidget(self.btn_AIF1TX2_3)
self.btn_AIF1TX2_4 = QtGui.QPushButton(self.gridLayoutWidget)
self.btn_AIF1TX2_4.setAcceptDrops(True)
self.btn_AIF1TX2_4.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1TX2_4.setText(_fromUtf8(""))
self.btn_AIF1TX2_4.setIcon(icon1)
self.btn_AIF1TX2_4.setFlat(True)
self.btn_AIF1TX2_4.setObjectName(_fromUtf8("btn_AIF1TX2_4"))
self.horizontalLayout_2.addWidget(self.btn_AIF1TX2_4)
self.verticalLayout_4.addLayout(self.horizontalLayout_2)
self.horizontalLayout_3.addLayout(self.verticalLayout_4)
self.gridLayout.addLayout(self.horizontalLayout_3, 1, 1, 1, 1)
self.lbl_playback = QtGui.QLabel(self.gridLayoutWidget)
self.lbl_playback.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.lbl_playback.setTextFormat(QtCore.Qt.AutoText)
self.lbl_playback.setObjectName(_fromUtf8("lbl_playback"))
self.gridLayout.addWidget(self.lbl_playback, 0, 0, 1, 1)
self.label_9 = QtGui.QLabel(self.gridLayoutWidget)
self.label_9.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.label_9.setAlignment(QtCore.Qt.AlignCenter)
self.label_9.setObjectName(_fromUtf8("label_9"))
self.gridLayout.addWidget(self.label_9, 0, 1, 1, 1)
self.dial = QtGui.QDial(self.centralwidget)
self.dial.setGeometry(QtCore.QRect(30, 360, 50, 64))
self.dial.setObjectName(_fromUtf8("dial"))
self.label_10 = QtGui.QLabel(self.centralwidget)
self.label_10.setGeometry(QtCore.QRect(20, 320, 52, 15))
self.label_10.setObjectName(_fromUtf8("label_10"))
self.widget = QtGui.QWidget(self.centralwidget)
self.widget.setGeometry(QtCore.QRect(160, 400, 331, 21))
self.widget.setObjectName(_fromUtf8("widget"))
self.groupBox = QtGui.QGroupBox(self.centralwidget)
self.groupBox.setGeometry(QtCore.QRect(130, 130, 361, 271))
self.groupBox.setObjectName(_fromUtf8("groupBox"))
self.graphicsView = WiringGraphicsView(self.groupBox)
self.graphicsView.setGeometry(QtCore.QRect(40, 30, 291, 241))
self.graphicsView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.graphicsView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.NoBrush)
self.graphicsView.setBackgroundBrush(brush)
self.graphicsView.setObjectName(_fromUtf8("graphicsView"))
self.btn_AIF1RX1_2 = DragButton(self.groupBox)
self.btn_AIF1RX1_2.setGeometry(QtCore.QRect(50, 50, 51, 31))
self.btn_AIF1RX1_2.setBaseSize(QtCore.QSize(0, 0))
self.btn_AIF1RX1_2.setMouseTracking(True)
self.btn_AIF1RX1_2.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1RX1_2.setText(_fromUtf8(""))
self.btn_AIF1RX1_2.setIcon(icon)
self.btn_AIF1RX1_2.setAutoDefault(False)
self.btn_AIF1RX1_2.setDefault(False)
self.btn_AIF1RX1_2.setFlat(True)
self.btn_AIF1RX1_2.setObjectName(_fromUtf8("btn_AIF1RX1_2"))
self.btn_AIF1TX1_5 = DragButton(self.groupBox)
self.btn_AIF1TX1_5.setGeometry(QtCore.QRect(270, 150, 41, 31))
self.btn_AIF1TX1_5.setMouseTracking(False)
self.btn_AIF1TX1_5.setFocusPolicy(QtCore.Qt.StrongFocus)
self.btn_AIF1TX1_5.setAcceptDrops(True)
self.btn_AIF1TX1_5.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1TX1_5.setText(_fromUtf8(""))
self.btn_AIF1TX1_5.setIcon(icon1)
self.btn_AIF1TX1_5.setFlat(True)
self.btn_AIF1TX1_5.setObjectName(_fromUtf8("btn_AIF1TX1_5"))
self.btn_AIF1RX1_3 = DragButton(self.groupBox)
self.btn_AIF1RX1_3.setGeometry(QtCore.QRect(60, 110, 51, 27))
self.btn_AIF1RX1_3.setBaseSize(QtCore.QSize(0, 0))
self.btn_AIF1RX1_3.setMouseTracking(True)
self.btn_AIF1RX1_3.setAcceptDrops(False)
self.btn_AIF1RX1_3.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1RX1_3.setText(_fromUtf8(""))
self.btn_AIF1RX1_3.setIcon(icon)
self.btn_AIF1RX1_3.setAutoDefault(False)
self.btn_AIF1RX1_3.setDefault(False)
self.btn_AIF1RX1_3.setFlat(True)
self.btn_AIF1RX1_3.setObjectName(_fromUtf8("btn_AIF1RX1_3"))
WolfsonMixerWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(WolfsonMixerWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 562, 23))
self.menubar.setObjectName(_fromUtf8("menubar"))
WolfsonMixerWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(WolfsonMixerWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
WolfsonMixerWindow.setStatusBar(self.statusbar)
self.retranslateUi(WolfsonMixerWindow)
QtCore.QObject.connect(self.dial, QtCore.SIGNAL(_fromUtf8("valueChanged(int)")), self.label_10.setNum)
QtCore.QMetaObject.connectSlotsByName(WolfsonMixerWindow)
def retranslateUi(self, WolfsonMixerWindow):
WolfsonMixerWindow.setWindowTitle(_translate("WolfsonMixerWindow", "Wolfson Mixer", None))
self.label_2.setText(_translate("WolfsonMixerWindow", "AIF1RX1", None))
self.label.setText(_translate("WolfsonMixerWindow", "L", None))
self.label_3.setText(_translate("WolfsonMixerWindow", "AIF1RX2", None))
self.label_4.setText(_translate("WolfsonMixerWindow", "R", None))
self.label_6.setText(_translate("WolfsonMixerWindow", "AIF1TX1", None))
self.label_5.setText(_translate("WolfsonMixerWindow", "L", None))
self.label_7.setText(_translate("WolfsonMixerWindow", "AIF1TX2", None))
self.label_8.setText(_translate("WolfsonMixerWindow", "R", None))
self.lbl_playback.setText(_translate("WolfsonMixerWindow", "<html><head/><body><p><span style=\" font-weight:600;\">Playback (from RPi)</span></p></body></html>", None))
self.label_9.setText(_translate("WolfsonMixerWindow", "<html><head/><body><p><span style=\" font-weight:600;\">Record (to RPi)</span></p></body></html>", None))
self.label_10.setText(_translate("WolfsonMixerWindow", "TextLabel", None))
self.groupBox.setTitle(_translate("WolfsonMixerWindow", "GroupBox", None))
from wiringgraphicsview import WiringGraphicsView
from dragbutton import DragButton
import icons_rc
Here is an example how to draw a line between two QWidgets in a QGraphicsScene. In principle it is straightforward. The rectangle of a widget can be accessed by QGraphicsProxyWidget.geometry() and is in scene coordinates. So one can draw a line based on that.
Example:
from PySide import QtGui, QtCore
app = QtGui.QApplication([])
scene = QtGui.QGraphicsScene()
# put a button into the scene and move it
button1 = QtGui.QPushButton('Button 1')
scene_button1 = scene.addWidget(button1)
r1 = scene_button1.geometry()
r1.moveTo(-100, -50)
scene_button1.setGeometry(r1)
# put another button into the scene
button2 = QtGui.QPushButton('Button 2')
scene_button2 = scene.addWidget(button2)
r2 = scene_button2.geometry()
# add a line between the centers of each rectangles
scene.addLine(r1.x() + r1.width() / 2, r1.y() + r1.height() / 2, r2.x() + r2.width() / 2, r2.y() + r2.height() / 2)
# view on the scene
view = QtGui.QGraphicsView(scene)
view.resize(300, 200)
view.show()
app.exec_()
And it looks like:
And now the whole with dragging because it is not that trivial. Not the QGraphicsProxyWidget but the original QWidget, seems to get the mouse move/pressed events. We simply emit a new signal (dragged) and connect it to a function that can move the button in the scene around (using the return of scene.addWidget, the QGraphicsProxyWidget which is also a QGraphicsItem). It also redraws the line between the two buttons so they stay connected.
from PySide import QtGui, QtCore
class DraggablePushButton(QtGui.QPushButton):
"""
Extension of QPushButton that emits a dragged signal (QPointF which is the delta in movement of the mouse) as
long as it is pressed.
"""
dragged = QtCore.Signal(QtCore.QPointF)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def mousePressEvent(self, event):
self.position = event.globalPos()
def mouseMoveEvent(self, event):
# will only by called if the mouse is also pressed
position_now = event.globalPos()
self.dragged.emit(position_now - self.position)
self.position = position_now
def move_scene_button1_and_redraw_line(drag):
# move the button1 by a certain delta position and change line connecting them with it
scene_button1.moveBy(drag.x(), drag.y())
r1 = scene_button1.geometry()
line_item.setLine(r1.x() + r1.width() / 2, r1.y() + r1.height() / 2, r2.x() + r2.width() / 2, r2.y() + r2.height() / 2)
app = QtGui.QApplication([])
# the graphicsscene
scene = QtGui.QGraphicsScene()
scene.setSceneRect(-150, -100, 300, 200)
# put a draggable button into the scene
button1 = DraggablePushButton('Button 1')
scene_button1 = scene.addWidget(button1)
scene_button1.setPos(-100, -50)
r1 = scene_button1.geometry()
# connect dragged events to move of scene button
button1.dragged.connect(move_scene_button1_and_redraw_line)
# put another still standing button into the scene
button2 = QtGui.QPushButton('Button 2')
scene_button2 = scene.addWidget(button2)
r2 = scene_button2.geometry()
# draw line between button1 and button2
line_item = scene.addLine(r1.x() + r1.width() / 2, r1.y() + r1.height() / 2, r2.x() + r2.width() / 2, r2.y() + r2.height() / 2)
# view on the scene
view = QtGui.QGraphicsView(scene)
view.resize(330, 220)
view.show()
app.exec_()
And it still looks like:

Categories

Resources