PyQt. можно ли нарисовать линию внутри экземпляра QGraphicsRectItem?

Рейтинг: 1Ответов: 1Опубликовано: 04.03.2023

Вопрос такой. Можно ли нарисовать линию внутри прямоугольника класса RectItem?
В интернете нашёл, что надо переопределить метод paint. Но как сделать это не пойму.

Мой код:

from PyQt6.QtWidgets import *
from PyQt6.QtCore import *
from PyQt6.QtGui import *
import sys

class RectItem(QGraphicsRectItem):
    
    def __init__(self, qrectf):
        super().__init__()
        self.qrectf = qrectf
        self.setRect(self.qrectf)
        self.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsMovable)
        
    def mouseMoveEvent(self, event):
        self.moveBy(event.pos().x() - event.lastPos().x(), event.pos().y() - event.lastPos().y())
       
class Scene(QGraphicsScene):
    
    def __init__(self): 
        super().__init__()
        self.setSceneRect(0,0,400,400)
        self.pos_x = 0
        self.pos_y = 0
        self.qrectf = None
        self.list_rect = []
        self.num_old = 0
    
    def add_qrectf(self, qrectf):
        self.qrectf = qrectf
    
    def add_rect(self, num):
        if num == 0:
            self.clear()
        
        elif num > self.num_old:        
            for i in range(self.num_old, num):
                rect = RectItem(self.qrectf)  
                rect.moveBy(self.qrectf.width()*i, 100)
                self.list_rect.append(rect)
                self.addItem(rect)
                
        elif num < self.num_old:
            for i in range(num, self.num_old):
                self.removeItem(self.list_rect[-1])
                self.list_rect.pop()
                
        else: pass
        
        self.num_old = num
        
    def num_rect_in_width():
        if self.width() % qrectf.width():
            n = self.width() // qrectf.width() + 1
        else: n = self.width() // qrectf.width()
        return n

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.scene = Scene()
        self.canvas = QGraphicsView()
        self.canvas.setScene(self.scene)
        self.qrectf = QRectF(0,0,50, 50)
        self.spinbox = QSpinBox()
        self.spinbox.valueChanged.connect(self.spinbox_event)
        
        layout = QHBoxLayout(self)
        layout.addWidget(self.canvas)
        layout.addWidget(self.spinbox)
        
        self.scene.add_qrectf(self.qrectf)
         
    def spinbox_event(self):
        self.scene.add_rect(self.spinbox.value())
   
if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = Window()
    w.show()
    app.exec()

Ответы

▲ 1Принят

Да, можно нарисовать линию внутри прямоугольника класса RectItem().

Как вариант, при создании экземпляра QGraphicsLineItem (Линия примитив) родителем сделайте объект класса RectItem().

import sys
'''
from PyQt6.QtWidgets import *
from PyQt6.QtCore import *
from PyQt6.QtGui import *
'''
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.Qt import *


class RectItem(QGraphicsRectItem):
    def __init__(self, qrectf):
        super().__init__()
        
        self.qrectf = qrectf
        self.setRect(self.qrectf)
        self.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsMovable)
        
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 
# ----------------------------------> vvvv <--------------------------
        self.line = QGraphicsLineItem(self)
        self.line.setPen(QPen(Qt.red, 2, Qt.SolidLine))
        self.line.setLine(0, 0, 50, 50) 
        self.line2 = QGraphicsLineItem(self)
        self.line2.setPen(QPen(Qt.green, 2, Qt.SolidLine))
        self.line2.setLine(QLineF(0, 50, 50, 0))
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        
    def mouseMoveEvent(self, event):
        self.moveBy(event.pos().x() - event.lastPos().x(), 
            event.pos().y() - event.lastPos().y())
      
      
class Scene(QGraphicsScene):
    def __init__(self): 
        super().__init__()
        
        self.setSceneRect(0, 0, 400, 400)
        self.pos_x = 0
        self.pos_y = 0
        self.qrectf = None
        self.list_rect = []
        self.num_old = 0
    
    def add_qrectf(self, qrectf):
        self.qrectf = qrectf
    
    def add_rect(self, num):
        if num == 0:
            self.clear()
        elif num > self.num_old:        
            for i in range(self.num_old, num):
                rect = RectItem(self.qrectf)  
                rect.moveBy(self.qrectf.width()*i, 100)
                self.list_rect.append(rect)
                self.addItem(rect)
        elif num < self.num_old:
            for i in range(num, self.num_old):
                self.removeItem(self.list_rect[-1])
                self.list_rect.pop()
        else: 
            pass
       
        self.num_old = num
        
    def num_rect_in_width():
        if self.width() % qrectf.width():
            n = self.width() // qrectf.width() + 1
        else: 
            n = self.width() // qrectf.width()
        return n
        

class Window(QWidget):
    def __init__(self):
        super().__init__()
        
        self.scene = Scene()
        self.canvas = QGraphicsView()
        self.canvas.setScene(self.scene)
        self.qrectf = QRectF(0, 0, 50, 50)
        self.spinbox = QSpinBox()
        self.spinbox.setRange(0, 8)                              # +
        self.spinbox.valueChanged.connect(self.spinbox_event)
        
        layout = QHBoxLayout(self)
        layout.addWidget(self.canvas)
        layout.addWidget(self.spinbox)
        
        self.scene.add_qrectf(self.qrectf)
         
    def spinbox_event(self):
        self.scene.add_rect(self.spinbox.value())
   
   
if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = Window()
    w.show()
    app.exec()

введите сюда описание изображения