I am trying to remove QTextDocument which is inside the QTextEdit but I am not able to do it. I used clear() method of QTextEdit but it won't clear the QTextEdit area. I also try to overwrite new document on previous by setting overwrite flag of QTextEdit but that doesn't work as well.
def create_doc(body_text):
doc = QTextDocument()
doc.setDocumentMargin(10)
cursor = QTextCursor(doc)
cursor.movePosition(QTextCursor.Start)
block_fmt = QTextBlockFormat()
block_fmt.setBottomMargin(6)
block_fmt.setAlignment(QtCore.Qt.AlignJustify)
para_fmt = QTextCharFormat()
para_fmt.setFontWeight(QFont.Normal)
para_fmt.setFontPointSize(12)
para_fmt.setFontFamilies(["Raleway", "Arial"])
cursor.insertBlock(block_fmt)
cursor.insertText(body_text, para_fmt)
cursor.movePosition(QTextCursor.End)
return doc
class AppUI(QtWidgets.QMainWindow):
def __init__(self):
super(AppUI, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.qTextEditArea.setOverwriteMode(True)
self.ui.button.clicked.connect(lambda : self.add_text("some text")
def add_text(self, text):
self.ui.qTextEditArea.clear()
document = create_doc(doc)
self.ui.qTextEditArea.setDocument(document)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ui = AppUI()
ui.show()
sys.exit(app.exec_())
If you know how to do it please help. Thanks
QTextEdit Class
document : QTextDocument*
This property holds the underlying document of the text editor.
Note: The editor does not take ownership of the document unless it is the document's parent object. The parent object of the provided document remains the owner of the object. If the previously assigned document is a child of the editor then it will be deleted.
Access functions:
QTextDocument * document() const
void setDocument(QTextDocument *document)
main.py
import sys
from PyQt5.Qt import *
from textEditArea import Ui_MainWindow
def create_doc(body_text):
doc = QTextDocument()
doc.setDocumentMargin(10)
cursor = QTextCursor(doc)
cursor.movePosition(QTextCursor.Start)
block_fmt = QTextBlockFormat()
block_fmt.setBottomMargin(6)
block_fmt.setAlignment(Qt.AlignJustify)
para_fmt = QTextCharFormat()
para_fmt.setFontWeight(QFont.Normal)
para_fmt.setFontPointSize(12)
para_fmt.setFontFamilies(["Raleway", "Arial"]) # This function was introduced in Qt 5.13.
cursor.insertBlock(block_fmt)
cursor.insertText(body_text, para_fmt)
cursor.movePosition(QTextCursor.End)
return doc
class AppUI(QMainWindow):
def __init__(self):
super(AppUI, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
# self.ui.qTextEditArea.setOverwriteMode(True)
self.ui.button.clicked.connect(lambda : self.add_text("some text"))
def add_text(self, text):
# self.ui.qTextEditArea.clear()
# document = create_doc(doc) # ??? (doc)
document = create_doc(text) # +++ text
self.ui.qTextEditArea.setDocument(document)
if __name__ == "__main__":
app = QApplication(sys.argv)
ui = AppUI()
ui.show()
sys.exit(app.exec_())
textEditArea.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(456, 304)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.qTextEditArea = QtWidgets.QTextEdit(self.centralwidget)
self.qTextEditArea.setObjectName("qTextEditArea")
self.gridLayout.addWidget(self.qTextEditArea, 0, 0, 1, 1)
self.button = QtWidgets.QPushButton(self.centralwidget)
self.button.setObjectName("button")
self.gridLayout.addWidget(self.button, 1, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 456, 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)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.button.setText(_translate("MainWindow", "PushButton"))
Related
I want to display an image using QGraphicsView in a window. I have a basic QGraphicsView and a button based test.ui file generated from QtDesigner tool. Corresponding test.py file:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'test.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(640, 480)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)
self.graphicsView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.graphicsView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.graphicsView.setObjectName("graphicsView")
self.verticalLayout.addWidget(self.graphicsView)
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setObjectName("pushButton")
self.verticalLayout.addWidget(self.pushButton)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 640, 26))
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)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "PushButton"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
I made use of QGraphicsScene to display an image inside this QGraphicsView. My current working solution is to mess up the above .py file as follows:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'test.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(640, 480)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.scene = QtWidgets.QGraphicsScene(self.centralwidget) #added
self.graphicsView = QtWidgets.QGraphicsView(self.scene) #edited
self.graphicsView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.graphicsView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.graphicsView.setObjectName("graphicsView")
self.verticalLayout.addWidget(self.graphicsView)
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setObjectName("pushButton")
self.verticalLayout.addWidget(self.pushButton)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 640, 26))
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)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "PushButton"))
self.pushButton.clicked.connect(self.display)
def display(self):
import imageio, numpy
self.scene.clear()
input_image = imageio.imread('image.jpg').copy()
height, width, channels = input_image.shape
bytesPerLine = channels * width
qimg = QtGui.QImage(input_image, width, height, bytesPerLine, QtGui.QImage.Format_RGB888)
self.pixmap = QtGui.QPixmap.fromImage(qimg)
self.scene.addPixmap(self.pixmap) #add pixmap to scene
self.graphicsView.scale(0.5,0.5)
self.scene.update()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
However, this solution is not systematic. I want to do the same without editing the original test.ui generated test.py file.
So, I tried following code which to me appears like a systematic translation of the previous working code. However, it fails to produce any display on button click:
from PyQt5 import QtCore, QtGui, QtWidgets
from test import Ui_MainWindow
class myWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent=parent)
self.setupUi(self)
self.scene = QtWidgets.QGraphicsScene(self.centralwidget) #append scene method
self.graphicsView = QtWidgets.QGraphicsView(self.scene) #graphicsView re-assigned with scene
self.pushButton.clicked.connect(self.display)
def display(self):
import imageio, numpy
self.scene.clear()
input_image = imageio.imread('image.jpg').copy()
height, width, channels = input_image.shape
bytesPerLine = channels * width
qimg = QtGui.QImage(input_image, width, height, bytesPerLine, QtGui.QImage.Format_RGB888)
self.pixmap = QtGui.QPixmap.fromImage(qimg)
self.scene.addPixmap(self.pixmap) #add pixmap to scene
self.graphicsView.scale(0.5,0.5)
self.scene.update()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = myWindow()
w.show()
sys.exit(app.exec_())
I am likely messing up something due to my limited understanding of class inheritance, QGraphicsView, and QGraphicsScene. Any pointers to my mistakes would be very helpful.
Note: I am using a myWindow class to integrate some key press functionality in future. I think the issue is more to do with how to selectively append/redefine few lines inside a parent class function. Is this even possible without re-writing the whole setupUi method? Or, is there another smarter way to perform the same task?
You have to set the scene to the existing QGraphicsView instead of creating a new QGraphicsView:
class myWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent)
self.setupUi(self)
self.scene = QtWidgets.QGraphicsScene(self.centralwidget)
self.graphicsView.setScene(self.scene)
self.pushButton.clicked.connect(self.display)
def display(self):
# ...
This is a sample code with just a push button and a textedit, i need to write line x line using a loop in a textedit when button is clicked.
The problem is that i need to implement threads because without them the program crashes or it doesn't write line x line, but all together when the loop ends;
and i need to implement in my application a textedit that shows info while the program loads "something".
So my question is, how to rewrite this code using threads to write in textedit when button is clicked?
The method i should run when the button is clicked is "write"
it should work like a print inside a for loop , it would print not all at once
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(640, 480)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
self.textEdit.setGeometry(QtCore.QRect(150, 220, 321, 71))
self.textEdit.setObjectName("textEdit")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(240, 100, 75, 23))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 640, 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)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "PushButton"))
self.pushButton.clicked.connect(self.write)
def write(self):
string=""
for i in range(1000):
string="\n"+str(i)
self.textEdit.insertPlainText(string)
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
First of all it is recommended not to modify the class generated by Qt Designer so you must regenerate the file and assume that it is called mainwindow.py: pyuic5 your_file.ui -o mainwindow.py -x.
Considering the above, the logic is to generate the information in another thread and send it to the GUI to modify it:
main.py
import threading
from PyQt5 import QtCore, QtGui, QtWidgets
from mainwindow import Ui_MainWindow
class WriterWorker(QtCore.QObject):
textChanged = QtCore.pyqtSignal(str)
def start(self):
threading.Thread(target=self._execute, daemon=True).start()
def _execute(self):
string = ""
for i in range(1000):
string = "\n"+str(i)
self.textChanged.emit(string)
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.writer_worker = WriterWorker()
self.writer_worker.textChanged.connect(self.on_text_changed)
self.pushButton.clicked.connect(self.writer_worker.start)
#QtCore.pyqtSlot(str)
def on_text_changed(self, text):
self.textEdit.insertPlainText(text)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
I am trying to create a table-widget where I can drop an audio file and populate the table with filename, size of file etc. My code is as follows. I haven't implemented the part for reading the metadata on dragEnterEvent as the table isn't even accepting drops of any kind.
from PyQt5 import QtCore, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(982, 615)
MainWindow.setAcceptDrops(True)
MainWindow.setStyleSheet("background-color: rgb(255, 255, 255);")
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(360, 0, 271, 181))
self.label.setText("")
self.label.setObjectName("label")
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget.setGeometry(QtCore.QRect(10, 200, 701, 331))
self.tableWidget.setAcceptDrops(True)
self.tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.tableWidget.setDragDropMode(QtWidgets.QAbstractItemView.DragDrop)
self.tableWidget.setDefaultDropAction(QtCore.Qt.CopyAction)
self.tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
self.tableWidget.setShowGrid(False)
self.tableWidget.setSortingEnabled(True)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.horizontalHeader().setVisible(True)
self.tableWidget.verticalHeader().setVisible(False)
self.tableWidget.setRowCount(6)
self.tableWidget.setColumnCount(6)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 982, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.titleUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def dragEnterEvent(self, event):
event.accept()
def dropEvent(self, event):
event.accept()
def titleUi(self, MainWindow):
MainWindow.setWindowTitle("tableWidget")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
How can I get the table to accept drops?
Firstly, you should import the file created by pyuic rather than editing it directly, otherwise all your edits will be lost if you make further changes in Qt Designer. (The example code below will show how to do that).
Secondly, you need to ensure that the table accepts drops and that it specifies the kinds of data it can receive. With that in place, you can then listen for drop events and add any dropped files to the table.
Before using the example below, you should re-run pyuic. The example assumes the ui module will saved as mainwindow.py in the same directory. If you want to use a different name, you will need to edit the import line accordingly.
import sys
from PyQt5 import QtCore, QtWidgets
from mainwindow import Ui_MainWindow
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.setWindowTitle('TableWidget')
self.tableWidget.setAcceptDrops(True)
self.tableWidget.viewport().installEventFilter(self)
types = ['text/uri-list']
types.extend(self.tableWidget.mimeTypes())
self.tableWidget.mimeTypes = lambda: types
self.tableWidget.setRowCount(0)
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.Drop and
event.mimeData().hasUrls()):
for url in event.mimeData().urls():
self.addFile(url.toLocalFile())
return True
return super().eventFilter(source, event)
def addFile(self, filepath):
row = self.tableWidget.rowCount()
self.tableWidget.insertRow(row)
item = QtWidgets.QTableWidgetItem(filepath)
self.tableWidget.setItem(row, 0, item)
self.tableWidget.resizeColumnToContents(0)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
I need to going to some directory when user click on button.
User enter path in QInputDialog (for example /mnt/data/Music on linux), and program go to this directory, like M-c in Midnight Commander or cd in ranger, but i don't know how i can do this... I already know all the documentation by heart
main.py
import sys
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWidgets import QMainWindow, QInputDialog
import exampleQTV
class PyMap(QMainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.search.clicked.connect(self.searchAction)
def searchAction(self):
text, ok = QInputDialog.getText(self, "Go to", "Enter path")
if ok:
path = text.split("/")
for item in path:
if item != "":
print("ITEM:", item)
self.leftView.keyboardSearch(item)
self.leftView.setExpanded(self.leftView.currentIndex(), True)
print("currentIndex():",self.leftView.model.filePath(self.leftView.currentIndex()))
child = self.leftView.currentIndex().child(0,0)
print("child:", self.leftView.model.filePath(child))
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.leftView = exampleQTV.exampleQTV()
self.leftView.setObjectName("leftView")
self.gridLayout.addWidget(self.leftView, 1, 0, 1, 1)
self.search = QtWidgets.QPushButton(self.centralwidget)
self.search.setObjectName("select")
self.gridLayout.addWidget(self.search, 0, 0, 1, 2)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 22))
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)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.search.setText(_translate("MainWindow", "Search"))
def main():
app = QtWidgets.QApplication(sys.argv)
window = PyMap()
window.show()
app.exec_()
if __name__ == '__main__':
main()
exampleQTV.py
from PyQt5.QtWidgets import QTreeView, QFileSystemModel
from PyQt5.QtCore import QDir
class exampleQTV(QTreeView):
def __init__(self):
QTreeView.__init__(self)
self.model = QFileSystemModel()
self.model.setRootPath(QDir.rootPath())
self.setModel(self.model)
self.eventCalled = False
self.requestForEscape = False
self.setColumnHidden(1, True)
self.setColumnHidden(2, True)
self.setColumnHidden(3, True)
self.expandAll()
If you want an item to be expanded your ancestors must be expanded, in the following code you implement that logic:
import sys
from PyQt5 import QtCore, QtWidgets
def expandPath(index, view):
if not index.isValid():
return
indexes = []
ix = index
while ix.isValid():
indexes.insert(0, ix)
ix = ix.parent()
for ix in indexes:
view.expand(ix)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
model = QtWidgets.QFileSystemModel()
model.setRootPath(QtCore.QDir.rootPath())
view = QtWidgets.QTreeView()
view.setModel(model)
view.setRootIndex(model.index(QtCore.QDir.rootPath()))
doc_directory = QtCore.QStandardPaths.writableLocation(
QtCore.QStandardPaths.DocumentsLocation
)
ix = model.index(doc_directory)
expandPath(ix, view)
view.resize(640, 480)
for i in (1, 2, 3):
view.setColumnHidden(i, True)
view.show()
sys.exit(app.exec_())
So I have this Ui_MainWindow class generated by pyuic5.
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'MainWindow.ui'
#
# Created by: PyQt5 UI code generator 5.9
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 450)
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setObjectName("centralWidget")
self.canvas = QtWidgets.QWidget(self.centralWidget)
self.canvas.setGeometry(QtCore.QRect(70, 30, 621, 341))
self.canvas.setAutoFillBackground(False)
self.canvas.setObjectName("canvas")
self.gview = QtWidgets.QGraphicsView(self.canvas)
self.gview.setGeometry(QtCore.QRect(80, 50, 256, 192))
self.gview.setObjectName("gview")
MainWindow.setCentralWidget(self.centralWidget)
self.menuBar = QtWidgets.QMenuBar(MainWindow)
self.menuBar.setGeometry(QtCore.QRect(0, 0, 800, 22))
self.menuBar.setObjectName("menuBar")
self.menuhola = QtWidgets.QMenu(self.menuBar)
self.menuhola.setObjectName("menuhola")
self.menust = QtWidgets.QMenu(self.menuBar)
self.menust.setObjectName("menust")
MainWindow.setMenuBar(self.menuBar)
self.menuBar.addAction(self.menuhola.menuAction())
self.menuBar.addAction(self.menust.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.menuhola.setTitle(_translate("MainWindow", "hola"))
self.menust.setTitle(_translate("MainWindow", "splendid"))
And I want to paint on something, as long as it's not the main window. However, no matter what I try, it just doesn't work.
Here's my code:
import sys
from PyQt5 import QtWidgets
from PyQt5.QtGui import QPainter
from src.qt_design.main_window import Ui_MainWindow
class SystemApp(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
def paintEvent(self, event):
# Nope
painter = QPainter(self.ui.gview)
painter.drawLine(0, 0, 50, 50)
# Nope
painter = QPainter(self.ui.canvas)
painter.drawLine(0, 0, 50, 50)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = SystemApp()
window.show()
sys.exit(app.exec_())
I'm not sure if I should either:
1. Paint with this parent on its children (like what I tried above)
2. Override children's paintEvent, but it's maybe a bad idea, see here
Any help will be appreciated!
You can get what you are trying to accomplish with an event filter
class SystemApp(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.gview.installEventFilter(self)
self.ui.canvas.installEventFilter(self)
def eventFilter(self, obj, e):
if e.type() == QtCore.QEvent.Paint:
painter = QPainter()
painter.begin(obj)
if obj == self.ui.canvas:
painter.setPen(QtCore.Qt.red) # Some specific painting
painter.drawLine(0, 0, 50, 50)
painter.end()
return True
return super().eventFilter(obj, e)