Как сделать что бы QLineEdit или QTextEdit размещённый на сцене был активным сразу после размещения?

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

Как сделать что бы QLineEdit/QTextEdit размещённый на сцене с помощью QGraphicsProxyWidget, сразу был активным и можно было сразу редактировать текст в этом QlineEdit? Основной код:

from PyQt5.Qt import *
from Sample1_ui import *
import sys

MODES = ('click', 'label')


class Mainwindow_S2(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.scene = Scene()
        self.scene.setSceneRect(0, 0, 500, 500)
        self.graphicsView.setScene(self.scene)
        self.scene.addRect(QRectF(0, 0, 500, 500), QPen(QColor(0, 0, 0)))
        mode_group = QButtonGroup(self)
        mode_group.setExclusive(True)
        for mode in MODES:
            btn = getattr(self, f'pushButton_{mode}')
            btn.pressed.connect(lambda mode=mode: self.scene.set_mode(mode))
            mode_group.addButton(btn)


class Scene(QGraphicsScene):
    def __init__(self):
        super().__init__()
        self.mode = 'label'

    def set_mode(self, mode):
        self.mode = mode

    def mousePressEvent(self, event):
        if self.mode == 'label':
            self.addItem(ProxyWidget(event.scenePos()))
        else:
            super().mousePressEvent(event)


class PLineEdit(QLineEdit):
    def __init__(self, proxy):
        super().__init__()
        self.font = QFont('Times New Roman', 15)
        self.font.setBold(True)
        self.font.setItalic(True)
        self.font.setUnderline(True)
        self.setFont(self.font)
        self.setStyleSheet(f'''background-color: transparent;\n
                               Border:0px dashed black;\n
                               color:black;\n''')
        self.setText('1123')
        self.setReadOnly(False)
        self.proxy = proxy

    def mouseDoubleClickEvent(self, event):
        self.proxy.selected = True
        self.setReadOnly(False)

    def keyPressEvent(self, event):
        super().keyPressEvent(event)
        if event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter:
            self.proxy.selected = False
            self.setReadOnly(True)


class ProxyWidget(QGraphicsProxyWidget):
    def __init__(self, pos):
        super().__init__()
        self.x = int(pos.x())
        self.y = int(pos.y())
        self.width = 80
        self.height = 30
        self.setAcceptHoverEvents(True)
        self.hover = False
        self.selected = True
        self.startPos = None
        self.widget = PLineEdit(self)
        self.setWidget(self.widget)
        self.setGeometry(QRectF(self.x, self.y, self.width, self.height))

    def boundingRect(self):
        return QRectF(0, 0, self.width, self.height)

    def paint(self, painter, option, widget):
        super().paint(painter, option, widget)
        painter.setPen(QPen(Qt.transparent))
        painter.setBrush(QBrush(Qt.transparent))
        painter.setRenderHints(QPainter.HighQualityAntialiasing)
        if self.selected:
            painter.setPen(QPen(Qt.red, 2, Qt.DashLine, cap=Qt.RoundCap))
            painter.setBrush(QBrush(Qt.transparent))
            rec = self.boundingRect()
            painter.drawRect(rec)
        elif self.hover:
            painter.setPen(QPen(Qt.black, 2, Qt.DashLine, cap=Qt.RoundCap))
            painter.setBrush(QBrush(Qt.transparent))
            rec = self.boundingRect()
            painter.drawRect(rec)

    def hoverMoveEvent(self, event):
        self.hover = True
        super().hoverMoveEvent(event)

    def hoverLeaveEvent(self, event):
        self.hover = False
        super().hoverLeaveEvent(event)

    def mousePressEvent(self, event):
        if event.button() == QtCore.Qt.LeftButton:
            self.startPos = event.pos()

    def mouseMoveEvent(self, event):
        if self.startPos:
            delta_x = event.pos().x() - self.startPos.x()
            delta_y = event.pos().y() - self.startPos.y()
            self.x = self.pos().x() + delta_x
            self.y = self.pos().y() + delta_y
        self.setPos(QPointF(self.x, self.y))
        self.update()

    def mouseReleaseEvent(self, event):
        self.startPos = None

if __name__ == '__main__':
    app = QApplication(sys.argv)
    graphics_view = Mainwindow_S2()
    graphics_view.show()
    sys.exit(app.exec_())

Ui из QtDesigner:

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1119, 830)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)
        self.graphicsView.setGeometry(QtCore.QRect(40, 60, 811, 561))
        self.graphicsView.setObjectName("graphicsView")
        self.pushButton_label = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_label.setGeometry(QtCore.QRect(920, 440, 111, 23))
        self.pushButton_label.setCheckable(True)
        self.pushButton_label.setChecked(True)
        self.pushButton_label.setObjectName("pushButton_label")
        self.pushButton_click = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_click.setGeometry(QtCore.QRect(940, 270, 111, 23))
        self.pushButton_click.setCheckable(True)
        self.pushButton_click.setObjectName("pushButton_click")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1119, 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_label.setText(_translate("MainWindow", "PushButton_label"))
        self.pushButton_click.setText(_translate("MainWindow", "PushButton_click"))


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_())

Ответы

▲ 0Принят

Помогло добавление строки self.widget.setFocus() в init для QGraphicsProxyWidget. Чтобы снять фокус после редактирования надо добавить self.proxy.scene().clearFocus() в keyPressEvent для QLineEdit. Добавление self.setFocus() в init для QLineEdit не работает.