Расположение одного виджета над другим, PyQt
Нужно чтобы пользователь мог рисовать поверх label
.
Хотелось бы сделать не прибегая к Layout
.
from PyQt6.QtWidgets import (QApplication, QWidget, QToolBar, QMainWindow, QLabel,
QScrollArea, QToolBar)
from PyQt6.QtGui import QImage, QAction, QKeySequence, QColor, QPixmap, QPainter, QPen
from PyQt6.QtCore import Qt, QPoint, QSize, QRect
from sys import argv
class Canvas(QLabel):
def __init__(self):
super().__init__()
self.setStyleSheet("background-color: #E0FFFF")
self.setScaledContents(False)
pixmap = QPixmap(2000, 1000)
pixmap.fill(QColor('transparent'))
#QtCore.Qt.transparent
#pixmap.fill(QtCore.Qt.transparent)
self.setPixmap(pixmap)
self.drawing = False
self.last_coords = None
self.test()
def minimumSize(self):
print(1)
return QSize(500, 500)
def set_drawing(self, drawing):
self.drawing = drawing
def mouseMoveEvent(self, e):
if self.drawing:
if self.last_coords is None:
self.last_coords = e.position()
return
canvas = self.pixmap()
painter = QPainter(canvas)
pen = painter.pen()
pen.setWidth(4)
pen.setColor(QColor('black'))
painter.setPen(pen)
painter.drawLine(self.last_coords, e.position())
painter.end()
self.setPixmap(canvas)
self.last_coords = e.position()
def mouseReleaseEvent(self, e):
self.last_coords = None
def reziseEvent(self, e):
print(1)
super().resizeEvent(e)
def test(self):
label = QLabel('test', self)
#label.setGeometry(QRect(self.geometry().left() + 50, 50, 50, 10))
label.move(50, 50)
self.show()
class NoteEditor(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('Note editor')
self.setGeometry(100, 100, 800, 600)
self.toolbar = QToolBar('Интрументы')
self.addToolBar(self.toolbar)
is_drawing_action = QAction('Рисовать', self)
is_drawing_action.setCheckable(True)
is_drawing_action.triggered.connect(self.set_drawing_action)
self.toolbar.addAction(is_drawing_action)
widget = QWidget()
scroll = QScrollArea()
self.canvas = Canvas()
scroll.setWidget(self.canvas)
self.setCentralWidget(scroll)
def set_drawing_action(self, state):
print(state)
self.canvas.set_drawing(state)
app = QApplication(argv)
window = NoteEditor()
window.show()
app.exec()
В документации нечего не смог найти на этот случай. Заранее спасибо!
Ответы (2 шт):
Sorry, вы не достаточно хорошо описываете проблему и то что вы хотите сделать.
Вы и так рисуете поверх label
, т.к. объект self.canvas
это и есть переопределенный класс QLabel()
.
Вы видимо хотите чтобы в вашем примере рисовалось и поверх объекта label
, который вы создаете в методе test()
.
Но так не получится, т.к. вы рисуете на объекте self.canvas
, а объект label
расположен над объектом self.canvas
но другой плоскости.
Если реализовывать ваш пример, то добавочный текст, на котором вы также хотите рисовать - необходимо также рисовать на объекте self.canvas
, используя drawText
.
Добавление дополнительного текста, для демонстрации вышесказанного, я реализовал в методе mousePressEvent(self, event)
по нажатию ПРАВОЙ кнопки мыши.
Теперь по добавленному тексту можно рисовать сверху и еще если вы кликните ПКМ по уже нарисованному, то этот текст отобразится поверх рисунка.
Поменяйте то что необходимо для PyQt6 и попробуйте:
'''
from PyQt6.QtWidgets import (QApplication, QWidget,
QToolBar, QMainWindow, QLabel, QScrollArea, QToolBar)
from PyQt6.QtGui import QImage, QAction, QKeySequence, \
QColor, QPixmap, QPainter, QPen
from PyQt6.QtCore import Qt, QPoint, QSize, QRect
'''
import sys
from PyQt5.Qt import *
class Canvas(QLabel):
def __init__(self):
super().__init__()
self.drawing = False
self.last_coords = None
self.leftButton = False # +++
self.setStyleSheet("background-color: #E0FFFF")
self.setScaledContents(False)
pixmap = QPixmap(2000, 1000)
pixmap.fill(QColor('transparent'))
self.setPixmap(pixmap)
self.test()
#? def minimumSize(self):
#? print(1)
#? return QSize(500, 500)
def set_drawing(self, drawing):
self.drawing = drawing
def mousePressEvent(self, event):
if event.button() == Qt.RightButton:
self.last_coords = event.pos()
canvas = self.pixmap()
painter = QPainter(canvas)
painter.setPen(QColor(250, 55, 55))
painter.setFont(QFont('Decorative', 18))
painter.drawText(self.last_coords,
f'вы кликнули: {self.last_coords.x()}/{self.last_coords.y()}')
painter.end()
self.setPixmap(canvas)
if event.button() == Qt.LeftButton: # +++
self.leftButton = True # +++
def mouseMoveEvent(self, e):
# ------------------------> vvvvvvvvvvvvvvv <-------------------# +++
if self.drawing and self.leftButton:
if self.last_coords is None:
# self.last_coords = e.position() # PyQt6
self.last_coords = e.pos() # PyQt5
return
canvas = self.pixmap()
painter = QPainter(canvas)
pen = painter.pen()
pen.setWidth(7)
pen.setColor(QColor('black'))
painter.setPen(pen)
# painter.drawLine(self.last_coords, e.position()) # PyQt6
painter.drawLine(self.last_coords, e.pos()) # PyQt5
painter.end()
self.setPixmap(canvas)
# self.last_coords = e.position() # PyQt6
self.last_coords = e.pos() # PyQt5
def mouseReleaseEvent(self, e):
self.last_coords = None
self.leftButton = False # +++
# ------> v v <----------------------------------------------------
# def reziseEvent(self, e):
def resizeEvent(self, e): # ??? для чего в этом классе
print(f'resizeEvent(self, e): {e.size()}')
super().resizeEvent(e)
def test(self):
label = QLabel('<H2 style="color: rgb(250, 55, 55);">Hello test</H2>', self)
label.move(50, 50)
self.show()
class NoteEditor(QMainWindow):
def __init__(self):
super().__init__()
self.toolbar = QToolBar('Интрументы')
self.addToolBar(self.toolbar)
is_drawing_action = QAction('Рисовать', self)
is_drawing_action.setCheckable(True)
is_drawing_action.triggered.connect(self.set_drawing_action)
self.toolbar.addAction(is_drawing_action)
# ? widget = QWidget()
scroll = QScrollArea()
self.canvas = Canvas()
scroll.setWidget(self.canvas)
self.setCentralWidget(scroll)
def set_drawing_action(self, state):
#print(state)
self.canvas.set_drawing(state)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = NoteEditor()
window.setWindowTitle('Note editor')
window.resize(800, 600)
window.show()
sys.exit(app.exec())
Нашёл решение с помощью использования lower
и raise_
. Главное чтобы располагались в одном родительском виджете.
Нужно было просто поднять PaintCanvas с помощью raise_. Спасибо кто помогал!