Search code examples
pythonpyside2

easy Qt widget to draw lines and shapes (like the tkinter canvas)?


I used to create GUIs with tkinter but i am trying to switch to PySide2 (which is way more customisable) but a can't find any PySide2 widget to replace the tkinter.canvas that i was using with tkinter.

I tried to use the QtGui.Qpainter widget but it seems very complicated compared to the tkinter canvas and I can't figure out how it works.

Did someone know an easy to use pyside widget which let me draw lines and shapes on it ?


Solution

  • Something similar to Tkinter Canvas Widget is Qt Graphics Framework that uses QGraphicsItems similar to Canvas Items. Since you don't ask for a specific example I will implement an example from the Tkinter docs to Qt:

    try:
        from Tkinter import *
    except ImportError:
        from tkinter import *
    
    
    master = Tk()
    
    w = Canvas(master, width=200, height=100)
    w.pack()
    
    w.create_line(0, 0, 200, 100)
    w.create_line(0, 100, 200, 0, fill="red", dash=(4, 4))
    
    w.create_rectangle(50, 25, 150, 75, fill="blue")
    
    mainloop()
    

    enter image description here

    import sys
    
    from PySide2 import QtCore, QtGui, QtWidgets
    
    if __name__ == "__main__":
        app = QtWidgets.QApplication(sys.argv)
    
        scene = QtWidgets.QGraphicsScene(QtCore.QRectF(0, 0, 200, 100))
        view = QtWidgets.QGraphicsView(
            scene, alignment=QtCore.Qt.AlignTop | QtCore.Qt.AlignHCenter
        )
        view.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        view.setBackgroundBrush(
            QtWidgets.QApplication.style()
            .standardPalette()
            .brush(QtGui.QPalette.Background)
        )
        view.setWindowTitle("Qt")
    
        line1 = scene.addLine(0, 0, 200, 100)
        line2 = scene.addLine(0, 100, 200, 0)
        pen = QtGui.QPen()
        pen.setDashPattern((4, 4))
        pen.setColor(QtGui.QColor("red"))
        line2.setPen(pen)
    
        rect = scene.addRect(QtCore.QRectF(QtCore.QPointF(50, 25), QtCore.QPointF(150, 75)))
        rect.setBrush(QtGui.QColor("blue"))
    
        view.resize(200, 100)
        view.show()
    
        sys.exit(app.exec_())
    

    enter image description here

    Equivalent items

    | Tk Items  | Qt Items                                                      |
    |-----------|---------------------------------------------------------------|
    | arc       | QGraphicsEllipseItem, QGraphicsPathItem                       |
    | bitmap    | QGraphicsPixmapItem                                           |
    | image     | QGraphicsPixmapItem                                           |
    | line      | QGraphicsLineItem, QGraphicsPathItem                          |
    | oval      | QGraphicsEllipseItem, QGraphicsPathItem                       |
    | polygon   | QGraphicsPolygonItem, QGraphicsPathItem                       |
    | rectangle | QGraphicsRectItem, QGraphicsPathItem                          |
    | text      | QGraphicsSimpleTextItem, QGraphicsTextItem, QGraphicsPathItem |
    | window    | QGraphicsProxyWidget                                          |