从上下文菜单将小部件添加到QMainWindow

时间:2019-11-11 13:49:02

标签: python pyqt5 qwidget

我可以将QWidget添加到QMainWindow并将其位置设置为光标位置。

但是我每次都想向QWidget添加新的QMainWindow。我可能没有给代码添加新的QWidget,但是在画布上,我只看到一个QWidget。这是我的代码:

from PyQt5.QtWidgets import QMainWindow, QApplication, QMenu, QMenuBar, QAction, QFileDialog, QWidget, QLabel
from PyQt5.QtGui import QIcon, QImage, QPainter, QPen, QBrush
from PyQt5.QtCore import Qt, QPoint
import sys


class Window(QMainWindow):
    def __init__(self):
        super().__init__()


        title = "Paint Application"
        top = 400
        left = 400
        width = 800
        height = 600
        self.objStr = "berkayy"
        self.count = 0

        # icon = "icons/pain.png"
        self.setAcceptDrops(True)
        self.setWindowTitle(title)
        self.setGeometry(top, left, width, height)
        # self.setWindowIcon(QIcon(icon))

        self.image = QImage(self.size(), QImage.Format_RGB32)
        self.image.fill(Qt.white)

        self.drawing = False
        self.brushSize = 2
        self.brushColor = Qt.black
        self.lastPoint = QPoint()

        mainMenu = self.menuBar()
        fileMenu = mainMenu.addMenu("File")
        brushSize = mainMenu.addMenu("Brush Size")
        brushColor = mainMenu.addMenu("Brush Color")

        saveAction = QAction(QIcon("icons/save.png"), "Save",self)
        saveAction.setShortcut("Ctrl+S")
        fileMenu.addAction(saveAction)
        saveAction.triggered.connect(self.save)

        clearAction = QAction(QIcon("icons/clear.png"), "Clear", self)
        clearAction.setShortcut("Ctrl+C")
        fileMenu.addAction(clearAction)
        clearAction.triggered.connect(self.clear)

        threepxAction = QAction( QIcon("icons/threepx.png"), "3px", self)
        brushSize.addAction(threepxAction)
        threepxAction.triggered.connect(self.threePixel)

        fivepxAction = QAction(QIcon("icons/fivepx.png"), "5px", self)
        brushSize.addAction(fivepxAction)
        fivepxAction.triggered.connect(self.fivePixel)

        sevenpxAction = QAction(QIcon("icons/sevenpx.png"),"7px", self)
        brushSize.addAction(sevenpxAction)
        sevenpxAction.triggered.connect(self.sevenPixel)

        ninepxAction = QAction(QIcon("icons/ninepx.png"), "9px", self)
        brushSize.addAction(ninepxAction)
        ninepxAction.triggered.connect(self.ninePixel)

        blackAction = QAction(QIcon("icons/black.png"), "Black", self)
        blackAction.setShortcut("Ctrl+B")
        brushColor.addAction(blackAction)
        blackAction.triggered.connect(self.blackColor)


        whitekAction = QAction(QIcon("icons/white.png"), "White", self)
        whitekAction.setShortcut("Ctrl+W")
        brushColor.addAction(whitekAction)
        whitekAction.triggered.connect(self.whiteColor)


        redAction = QAction(QIcon("icons/red.png"), "Red", self)
        redAction.setShortcut("Ctrl+R")
        brushColor.addAction(redAction)
        redAction.triggered.connect(self.redColor)

        greenAction = QAction(QIcon("icons/green.png"), "Green", self)
        greenAction.setShortcut("Ctrl+G")
        brushColor.addAction(greenAction)
        greenAction.triggered.connect(self.greenColor)

        yellowAction = QAction(QIcon("icons/yellow.png"), "Yellow", self)
        yellowAction.setShortcut("Ctrl+Y")
        brushColor.addAction(yellowAction)
        yellowAction.triggered.connect(self.yellowColor)

    def rectangle(self, e, pos):
        print(pos)
        painter = QPainter(self)
        painter.setPen(QPen(Qt.black, 5, Qt.SolidLine))
        painter.setBrush(QBrush(Qt.green, Qt.DiagCrossPattern))

        painter.drawRect(100, 15, 400, 200)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.drawing = True
            self.lastPoint = event.pos()
            #print(self.lastPoint)

    def contextMenuEvent(self, event):
        contextMenu = QMenu(self)
        newAct = contextMenu.addAction("New")
        openAct = contextMenu.addAction("Open")
        closeAct = contextMenu.addAction("Close")

        action = contextMenu.exec_(self.mapToGlobal(event.pos()))
        if action == closeAct:
            self.close()
        elif action == openAct:
            self.berkay(event.pos())

    def mouseMoveEvent(self, event):
        if(event.buttons() & Qt.LeftButton) & self.drawing:
            painter = QPainter(self.image)
            painter.setPen(QPen(self.brushColor, self.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
            painter.drawLine(self.lastPoint, event.pos())
            self.lastPoint = event.pos()
            self.update()

    def berkay(self, pos):
        wid = QWidget(self)
        btn = QLabel(wid)
        btn.setText("skjdf")
        btn.setObjectName(self.objStr + str(self.count) )
        btn.move(pos)
        self.setCentralWidget(wid)
        self.count += 1
        # btn.setDragEnabled(True)
        print(btn.objectName())
        # self.show()

    def mouseReleaseEvent(self, event):

        if event.button() == Qt.LeftButton:
            self.drawing = False


    def paintEvent(self, event):
        canvasPainter = QPainter(self)
        canvasPainter.drawImage(self.rect(),self.image, self.image.rect() )

    def save(self):
        filePath, _ = QFileDialog.getSaveFileName(self, "Save Image", "", "PNG(*.png);;JPEG(*.jpg *.jpeg);;All Files(*.*) ")

        if filePath == "":
            return
        self.image.save(filePath)

    def clear(self):
        self.image.fill(Qt.white)
        self.update()

    def threePixel(self):
        self.brushSize = 3

    def fivePixel(self):
        self.brushSize = 5

    def sevenPixel(self):
        self.brushSize = 7

    def ninePixel(self):
        self.brushSize = 9

    def blackColor(self):
        self.brushColor = Qt.black

    def whiteColor(self):
        self.brushColor = Qt.white

    def redColor(self):
        self.brushColor = Qt.red

    def greenColor(self):
        self.brushColor = Qt.green

    def yellowColor(self):
        self.brushColor = Qt.yellow

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    app.exec()

我想在用户每次单击上下文菜单项时创建新的QWidget

2 个答案:

答案 0 :(得分:1)

QMainWindow只能有一个中央小部件。因此,添加新的QLabel作为中央窗口小部件将删除之前的窗口小部件。这就是为什么您只能看到最后一个标签的原因。

创建一个小部件并将其定义为中央小部件。然后,将标签添加为中央小部件的子级:

class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.area = QWidget(self)
        self.setCentralWidget(self.area)

    def berkay(self, pos):
        btn = QLabel("BOOH", self.area)
        btn.move(self.area.mapFromParent(pos)) # Map the pos in the coord system of self.area
        btn.show()

答案 1 :(得分:0)

首先,对于每个单个小部件,将x和y值存储在列表中。之后,将新的和当前的小部件添加到窗口中央小部件中。

修改

我们不再需要存储窗口小部件x和y。

感谢Romha提供优化建议。

import sys
from PyQt5.QtWidgets import QMainWindow, QMenu, QApplication, QWidget, QPushButton, qApp
from PyQt5 import QtGui, QtCore
from PyQt5.QtCore import Qt

class Example(QMainWindow):
    def __init__(self):
        super().__init__()
        self.area = QWidget(self)
        self.setCentralWidget(self.area)
        self.initUI()

    def initUI(self):         
        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('Context menu')
        self.setStyleSheet("QMainWindow {background: 'white';}")
        self.show()

    def contextMenuEvent(self, event):
        cmenu = QMenu(self)
        addBtnAct = cmenu.addAction("Add Button")
        quitAct = cmenu.addAction("Quit")
        action = cmenu.exec_(self.mapToGlobal(event.pos()))
        if action == quitAct:
            qApp.quit()
        elif action == addBtnAct:
            self.addLabel(event.pos())

    def addLabel(self, pos):
        btn = QLabel("BOOH", self.area)
        btn.move(self.area.mapFromParent(pos)) # Map the pos in the coord system of self.area
        btn.show()

if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())