Проблема с отображением QMenu в PyQt5 - PullRequest
0 голосов
/ 12 июня 2019

Я пытаюсь отобразить QMenu, если щелкнуть правой кнопкой мыши строку QTableWidget. Проблема в том, что всякий раз, когда появляется меню, оно отображается в виде точки. Ниже вы можете найти минимальный воспроизводимый пример.

import sys

from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import (QApplication, QAction, QMenu, QTableWidget,
                             QAbstractItemView)


class PhotoSetTable(QTableWidget):
    _menu = None

    def __init__(self, parent=None):
        super().__init__(parent)

        self.setRowCount(0)
        self.setColumnCount(2)
        self.setHorizontalHeaderLabels(["Name", "Count"])
        self.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self._menu = self._generate_menu()
        row_position = self.rowCount()
        self.insertRow(row_position)
        name_item = QtWidgets.QTableWidgetItem("asd")
        name_item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        count_item = QtWidgets.QTableWidgetItem("0")
        count_item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        self.setItem(row_position, 0, name_item)
        self.setItem(row_position, 1, count_item)


        #self._refresh()

    @staticmethod
    def _generate_menu():
        menu = QMenu()
        menu.addAction(QAction("Quit"))
        menu.addSeparator()
        menu.addAction(QAction("WUUU"))
        menu.addSeparator()

        return menu

    def mousePressEvent(self, e):
        super().mousePressEvent(e)
        if e.buttons() == QtCore.Qt.RightButton:
            item = self.itemAt(e.pos())

            if item is not None:
                self._menu.exec(e.globalPos())


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

Что вызывает такое поведение?

Ответы [ 2 ]

2 голосов
/ 12 июня 2019

Проблема заключается в добавлении QAction в сгенерированное контекстное меню.Вместо этого попробуйте добавить пункты меню с именем элемента в виде строки в качестве первого параметра и метода, который он должен вызывать в качестве второго.

@staticmethod
def _generate_menu():
    menu = QMenu()
    menu.addAction("Quit", lambda: print('quitting'))
    menu.addSeparator()
    menu.addAction("WUUU", method_name)
    menu.addSeparator()

    return menu
1 голос
/ 10 июля 2019

Причина, по которой вы видите только «точку», заключается в том, что вы на самом деле видите пустое меню, поскольку вы создаете QActions без родителей.
QMenu.addAction(QAction*) не передает владение QAction в меню (оно ведет себя как QWidget.addAction, как объяснено здесь , поскольку QMenu является потомком QWidget), что означает, что как только метод _generate_menu() вернется, эти действия «передаются» сборщику мусора в Python (он же удален).

Если по какой-либо причине вам действительно необходимо создать «автономные» QActions, добавить к ним родительский элемент (или сделать их свойством какого-либо персистентного объекта, даже путем добавления к другому постоянному объекту, например списку или кортежу) или просто используйте menu.addAction(str) как указано MalloyDelacroix.
Кстати, если вы просто установите меню в качестве родителя, этого будет достаточно:

    menu.addAction(QAction("Quit", menu))

При этом, по крайней мере, согласно вашему примеру, на самом деле нет необходимости использовать статический метод для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...