首页 > 解决方案 > 添加新后如何在托盘菜单中刷新

问题描述

添加新项目后,我需要刷新托盘菜单上的列表。

我需要做什么

class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
    def __init__(self, icon, parent=None):
        QtWidgets.QSystemTrayIcon.__init__(self, icon, parent)
        menu = QtWidgets.QMenu(parent)

        c.execute('SELECT * FROM projects')
        for row in c.fetchall():
                path = row[0]
                open_app = menu.addAction(path.split('/')[-1])
                open_app.triggered.connect( lambda: self.vscode(path))           

    def add(self):
        Tkinter.Tk().withdraw() # Close the root window
        in_path = tkFileDialog.askdirectory()
        c.execute("INSERT INTO projects VALUES ('"+str(in_path)+"')")

标签: pythonpyside2qtwidgets

解决方案


一种可能的解决方案是消除依赖于数据库的 QAction,并通过将新信息插入它们来创建新的:

from PySide2 import QtCore, QtGui, QtWidgets, QtSql


def create_connection():
    db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
    db.setDatabaseName("tray.db")

    if not db.open():
        QtWidgets.QMessageBox.critical(
            None,
            QtWidgets.qApp.tr("Cannot open database"),
            QtWidgets.qApp.tr(
                "Unable to establish a database connection.\n"
                "This example needs SQLite support. Please read "
                "the Qt SQL driver documentation for information "
                "how to build it.\n\n"
                "Click Cancel to exit."
            ),
            QtWidgets.QMessageBox.Cancel,
        )
        return False

    query = QtSql.QSqlQuery(
        "CREATE TABLE IF NOT EXISTS projects(PATH text NOT NULL UNIQUE)"
    )
    if not query.exec_():
        print(query.lastError().text())
        return False
    return True


class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
    def __init__(self, icon, parent=None):
        super().__init__(icon, parent)
        self._path_actions = []

        self._menu = QtWidgets.QMenu(parent)
        self.setContextMenu(self._menu)

        self._separator = self._menu.addSeparator()
        add_action = QtWidgets.QAction(
            "Adicionar", self, icon=QtGui.QIcon("img/plus.png"), triggered=self.add
        )
        quit_action = QtWidgets.QAction(
            "Exit",
            self,
            icon=QtGui.QIcon("img/logout.png"),
            triggered=QtWidgets.QApplication.quit,
        )
        self._menu.addAction(add_action)
        self._menu.addAction(quit_action)

        self.refresh_menu()

        self.activated.connect(self.onTrayIconActivated)

    @QtCore.Slot(QtWidgets.QSystemTrayIcon.ActivationReason)
    def onTrayIconActivated(self, reason):
        if reason in (
            QtWidgets.QSystemTrayIcon.Trigger,
            QtWidgets.QSystemTrayIcon.DoubleClick,
        ):
            QtWidgets.QApplication.quit()

    def refresh_menu(self):
        menu = self.contextMenu()

        for action in self._path_actions:
            action.deleteLater()

        query = QtSql.QSqlQuery("SELECT * FROM projects")
        self._path_actions = []
        while query.next():
            directory = query.value(0)
            info = QtCore.QFileInfo(directory)
            action = QtWidgets.QAction(info.fileName(), self, triggered=self.vscode)
            action.setData(directory)
            self._path_actions.append(action)
        menu.insertActions(self._separator, self._path_actions)

    @QtCore.Slot()
    def add(self):
        directory = QtWidgets.QFileDialog.getExistingDirectory(
            None, self.tr("Open getExistingDirectory")
        )
        query = QtSql.QSqlQuery()
        query.prepare("INSERT INTO projects VALUES (?)")
        query.addBindValue(directory)
        if not query.exec_():
            print(query.lastError().text())
            return
        self.refresh_menu()

    @QtCore.Slot()
    def vscode(self):
        action = self.sender()
        directory = action.data()
        print(directory)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)

    if not create_connection():
        sys.exit(-1)

    if not QtWidgets.QSystemTrayIcon.isSystemTrayAvailable():
        QtWidgets.QMessageBox.critical(
            None, "Systray", "I couldn't detect any system tray on this system."
        )
        sys.exit(1)

    QtWidgets.QApplication.setQuitOnLastWindowClosed(False)
    tray_icon = SystemTrayIcon(QtGui.QIcon("img/icon.png"))
    tray_icon.show()
    tray_icon.showMessage("TrayCode", 'Hi "bitter"')
    sys.exit(app.exec_())

推荐阅读