Как нормально сделать action, чтобы после его создания можно было запускать файлы?

Как нормально сделать action, чтобы после его создания можно было запускать файлы?

При создании файла, он попадает в список "Файлы". Например: мы создаем файл NEW 3, а затем сохраняем и выключаем. Чтобы открыть этот файл, мы можем нажать на ранее созданный action - NEW 3 в списке "Файлы".

Я пытался написать что-то на подобие класса Widget() пока не выходит.

введите сюда описание изображения

import sys

from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QFileDialog, QMessageBox
from PyQt5.QtWidgets import *

class Widget(QtWidgets.QWidget):
    def __init__(self, val):
        super().__init__()
        self.textEdit = QtWidgets.QTextEdit(f'{val}' * 10, self)
        v_layout = QtWidgets.QVBoxLayout(self)
        v_layout.addWidget(self.textEdit)


class App(QtWidgets.QWidget):
    def __init__(self, parent):
        super().__init__()
        self.parent = parent
    def create_file(self):
        self.tab = Widget(self.parent.val)
        self.tab.setObjectName("tab")
        self.parent.tabWidget.addTab(self.tab, "")
        str = f"NEW {self.parent.val}"
        self.parent.tabWidget.setTabText(self.parent.tabWidget.indexOf(self.tab), str)
        self.parent.val += 1
        self.action_3 = QtWidgets.QAction(self)
        self.action_3.setText(str)
        self.parent.menu_2.addAction(self.action_3)


    def close_tab(self, ind):
        self.parent.tabWidget.removeTab(ind)

    def save(self):
        path, _ = QFileDialog.getOpenFileName(self, 'Take file', '')
        text = self.tab.textEdit.toPlainText()
        with open(path, "w") as file:
            file.write(text)

class Ui_MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.app = App(self)
        self.tabWidget.setTabsClosable(True)
        self.tabWidget.tabCloseRequested.connect(self.app.close_tab)
        self.action_2.triggered.connect(self.app.create_file)
        self.action.triggered.connect(self.app.save)
        self.val = 0

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(381, 265)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setGeometry(QtCore.QRect(10, 10, 361, 201))
        self.tabWidget.setObjectName("tabWidget")
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 381, 21))
        self.menubar.setObjectName("menubar")
        self.menu = QtWidgets.QMenu(self.menubar)
        self.menu.setObjectName("menu")
        self.menu_2 = QtWidgets.QMenu(self.menu)
        self.menu_2.setObjectName("menu_2")
        MainWindow.setMenuBar(self.menubar)
        self.action = QtWidgets.QAction(MainWindow)
        self.action.setObjectName("action")
        self.action_2 = QtWidgets.QAction(MainWindow)
        self.action_2.setObjectName("action_2")
        self.menu.addAction(self.action)
        self.menu.addAction(self.action_2)
        self.menu.addAction(self.menu_2.menuAction())
        self.menubar.addAction(self.menu.menuAction())

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        self.show()

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.menu.setTitle(_translate("MainWindow", "Файл"))
        self.menu_2.setTitle(_translate("MainWindow", "Файлы"))
        self.action.setText(_translate("MainWindow", "Сохранить"))
        self.action_2.setText(_translate("MainWindow", "Новый файл"))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ui = Ui_MainWindow()
    sys.exit(app.exec_())

Ответы (1 шт):

Автор решения: S. Nick

Если я правильно понял вашу задумку, то вот вам вариант ее реализации:

import sys
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QFileDialog, QMessageBox
from PyQt5.QtWidgets import *


class Widget(QtWidgets.QWidget):
    def __init__(self, val):
        super().__init__()
        self.textEdit = QtWidgets.QTextEdit(f'{val}' * 10, self)
        v_layout = QtWidgets.QVBoxLayout(self)
        v_layout.addWidget(self.textEdit)


class App(QtWidgets.QWidget):
    def __init__(self, parent):
        super().__init__()
        self.parent = parent
        
        self.menuAction_3 = []                                                         # +++
        
    def create_file(self):
        self.tab = Widget(self.parent.val)
        self.tab.setObjectName(f"tab {self.parent.val}")
        self.parent.tabWidget.addTab(self.tab, "")
        _str = f"NEW {self.parent.val}"
        self.parent.tabWidget.setTabText(self.parent.tabWidget.indexOf(self.tab), _str)
        self.parent.val += 1
        self.action_3 = QtWidgets.QAction(self)
        self.action_3.setText(_str)
        self.action_3.triggered.connect(lambda checked, val=_str: self.goFile(val))     # +++
        self.parent.menu_2.addAction(self.action_3)
        
        d = {_str: self.action_3}                                                       # +++
        self.menuAction_3.append(d)                                                     # +++                     

# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
    @QtCore.pyqtSlot(int)                                       
    def close_tab(self, index):
        _tabText = self.parent.tabWidget.tabText(index)       
        widget = self.parent.tabWidget.widget(index)          
        # if the widget exists
        if widget:
            # removes the widget
            widget.deleteLater()
        # removes the tab of the QTabWidget
        self.parent.tabWidget.removeTab(index)

        _ind, _action  = [ 
            [i, v.get(_tabText) ] for i, v in enumerate(self.menuAction_3) \
                if v.get(_tabText, None) is not None
        ][0]
        self.parent.menu_2.removeAction(_action)
        self.menuAction_3.pop(_ind)

    def save(self):
        if not self.parent.tabWidget.count():
            return
        path, _ = QFileDialog.getOpenFileName(self, 'Take file', '')
        if path:                                         
            ind  = self.parent.tabWidget.currentIndex()
            if ind != -1:
                text = self.parent.tabWidget.currentWidget().textEdit.toPlainText()               
                with open(path, "w") as file:
                    file.write(text)
            
    def goFile(self, value):
        _ind, _action  = [ 
            [i, v.get(value) ] for i, v in enumerate(self.menuAction_3) \
                if v.get(value, None) is not None
        ][0]
        path, _ = QFileDialog.getOpenFileName(self, 'Take file', '')
        if path:
            self.parent.tabWidget.setCurrentIndex(_ind)
            with open(path, "r") as file:
                text = file.read()
            self.parent.tabWidget.currentWidget().textEdit.setPlainText(text)
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    

class Ui_MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.app = App(self)
        self.tabWidget.setTabsClosable(True)
        self.tabWidget.tabCloseRequested.connect(self.app.close_tab)
        self.action_2.triggered.connect(self.app.create_file)
        self.action.triggered.connect(self.app.save)
        self.val = 0

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(381, 265)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setGeometry(QtCore.QRect(10, 10, 361, 201))
        self.tabWidget.setObjectName("tabWidget")
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 381, 21))
        self.menubar.setObjectName("menubar")
        
        self.menu = QtWidgets.QMenu(self.menubar)
        self.menu.setObjectName("menu")
        self.menu_2 = QtWidgets.QMenu(self.menu)
        self.menu_2.setObjectName("menu_2")
        MainWindow.setMenuBar(self.menubar)
        self.action = QtWidgets.QAction(MainWindow)
        self.action.setObjectName("action")
        
        self.action_2 = QtWidgets.QAction(MainWindow)
        self.action_2.setObjectName("action_2")
        
        self.menu.addAction(self.action)
        self.menu.addAction(self.action_2)
        self.menu.addAction(self.menu_2.menuAction())
        self.menubar.addAction(self.menu.menuAction())

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        self.show()

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.menu.setTitle(_translate("MainWindow", "Файл"))
        self.menu_2.setTitle(_translate("MainWindow", "Файлы"))
        self.action.setText(_translate("MainWindow", "Сохранить"))
        self.action_2.setText(_translate("MainWindow", "Новый файл"))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ui = Ui_MainWindow()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка