Home > OS >  How to call a QTextEdit widget from MainWindow and use it from another class? [pyqt5, pyside, python
How to call a QTextEdit widget from MainWindow and use it from another class? [pyqt5, pyside, python

Time:08-14

I am trying to use the self.textedit = qtw.QTextEdit() widget that I declared from my MainWindow into my TextFileOpenedInNewTab class by doing this self.main_window = MainWindow() and using it like this self.main_window.textedit.setPlainText(content). It works, but it has a bug. It opens a new window. which I do not intend to happen.

How do I properly use or call a widget I declared from another class in PyQt?

import sys
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg

import resources 
# how to import resources: https://www.youtube.com/watch?v=QdOoZ7edqXc&list=PLXlKT56RD3kBu2Wk6ajCTyBMkPIGx7O37&index=4


class TextFileOpenedInNewTab(qtw.QMainWindow):
    def __init__(self, content):
        super().__init__()

        # get the textedit from the MainWindow
        self.main_window = MainWindow()
         # text edit
        self.main_window.textedit.setPlainText(content)
        # making tabs as central widget
        self.setCentralWidget(self.main_window.textedit)

class BlankTab(qtw.QMainWindow):
    def __init__(self):
        super().__init__()
        self.textedit = qtw.QTextEdit()
        self.setCentralWidget(self.textedit)


class MainWindow(qtw.QMainWindow):
    def __init__(self):
        super().__init__()
        
        # text edit
        self.textedit = qtw.QTextEdit()
        
        # status bar
        self.statusbar = self.statusBar()
        self.statusbar.showMessage('Ready')
        
        self.setWindowTitle("Tab Widget Application")
        self.setWindowIcon(qtg.QIcon("./_icons/notepad.png"))
        
        """     Tabs        """ 
        # creating a tab widget
        self.tabs = qtw.QTabWidget()
        # making tabs closeable
        self.tabs.setTabsClosable(True)
        # this code allow the use of creating new tabs  
        self.tabs.setDocumentMode(True)
        # adding action when double clicked
        self.tabs.tabBarDoubleClicked.connect(self.tab_open_doubleclick)
        # adding action when tab close is requested
        self.tabs.tabCloseRequested.connect(self.close_current_tab)
        # making tabs as central widget
        self.setCentralWidget(self.tabs)
        # creating first tab
        self.add_new_tab("Untitled.txt")

        """     Menubar QMenus       """
        self.menuBar_open()
        self.menuBar_exit_file()

        self.initUI()
        self.show()
        
    def initUI(self):

        """     UI Functionalities       """
        menubar = self.menuBar()
        file_menu = menubar.addMenu('File')
        file_menu.addAction(self.open_file)
        file_menu.addSeparator()
        file_menu.addAction(self.exit_program) 

    def menuBar_open(self):
        self.open_file = qtw.QAction(qtg.QIcon(':/images/folder.png'),"Open...", self)
        self.open_file.setShortcut('Ctrl O')
        self.open_file.setStatusTip('Open a file')
        self.open_file.triggered.connect(self.openFile)

    def menuBar_exit_file(self):
        self.exit_program = qtw.QAction(qtg.QIcon(':/images/close.png'), "Exit", self)
        self.exit_program.setShortcut('Ctrl Q')
        self.exit_program.setStatusTip('Exit Program')
        self.exit_program.triggered.connect(self.close)


    # method for adding new tab
    def add_new_tab(self, label ="Untitled.txt"):

        # setting tab index
        index = self.tabs.addTab(BlankTab(), label)
        self.tabs.setCurrentIndex(index)


    # when double clicked is pressed on tabs
    def tab_open_doubleclick(self, index):
        
        # checking index i.e
        # No tab under the click
        if index == -1:
            # creating a new tab
            self.add_new_tab()


    # when tab is closed
    def close_current_tab(self, index):

        # if there is only one tab
        if self.tabs.count() < 2:
            # do nothing
            return
        # else remove the tab
        self.tabs.removeTab(index)


    def openFile(self):
        options = qtw.QFileDialog.Options()
        filenames, _ = qtw.QFileDialog.getOpenFileNames(
            self, 'Open a file', '',
            'All Files (*);;Python Files (*.py);;Text Files (*.txt)',
            options=options
        )
        if filenames:
            for filename in filenames:
                with open(filename, 'r') as file_o:
                    content = file_o.read()
                    self.tabs.addTab(TextFileOpenedInNewTab(str(content)), str(filename))


    def closeTab(self, index):
        tab = self.tabs.widget(index)
        tab.deleteLater()
        self.tabs.removeTab(index)


if __name__ == "__main__":
    app = qtw.QApplication.instance()
    if app is None:            
        # in every pyqt application it is required to create the object of QApplication
        app = qtw.QApplication(sys.argv)
    else:
        print('QApplication instance already exists: %s' % str(app))
        
    main = MainWindow()
    main.show()
    try:
        sys.exit(app.exec_())
    except SystemExit:
        print("Closing Window...") 

CodePudding user response:

That is because you are creating a new QMainWindow every time you open a new tab.

Both your BlankTab class and TextFileOpenedInNewTab class are subclassing QMainWindow so every time their constructors are called it is creating a separate window for each of them. Both classes are unnecessary for what you are trying to achieve.

When creating a new tab the only widget constructor that needs to be called is the QTextEdit.

Try it like this: I made some additional notes in the code where I made changes

import sys
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg

class MainWindow(qtw.QMainWindow):
    def __init__(self):
        super().__init__()
        self.textedit = qtw.QTextEdit()
        self.statusbar = self.statusBar()
        self.statusbar.showMessage('Ready')
        self.setWindowTitle("Tab Widget Application")
        self.setWindowIcon(qtg.QIcon("./_icons/notepad.png"))
        self.tabs = qtw.QTabWidget(self)
        self.tabs.setTabsClosable(True)
        self.tabs.setDocumentMode(True)
        self.tabs.tabBarDoubleClicked.connect(self.tab_open_doubleclick)
        self.tabs.tabCloseRequested.connect(self.close_current_tab)
        self.setCentralWidget(self.tabs)
        self.add_new_tab("Untitled.txt")
        self.menuBar_open()
        self.menuBar_exit_file()
        self.initUI()

    def initUI(self):
        menubar = self.menuBar()
        file_menu = menubar.addMenu('File')
        file_menu.addAction(self.open_file)
        file_menu.addSeparator()
        file_menu.addAction(self.exit_program)

    def menuBar_open(self):
        self.open_file = qtw.QAction(qtg.QIcon(':/images/folder.png'),"Open...", self)
        self.open_file.setShortcut('Ctrl O')
        self.open_file.setStatusTip('Open a file')
        self.open_file.triggered.connect(self.openFile)

    def menuBar_exit_file(self):
        self.exit_program = qtw.QAction(qtg.QIcon(':/images/close.png'), "Exit", self)
        self.exit_program.setShortcut('Ctrl Q')
        self.exit_program.setStatusTip('Exit Program')
        self.exit_program.triggered.connect(self.close)

    def add_new_tab(self, label ="Untitled.txt"):
        index = self.tabs.addTab(qtw.QTextEdit(), label)  # create a new blank text edit widget
        self.tabs.setCurrentIndex(index)

    def tab_open_doubleclick(self, index):
        if index == -1:
            self.add_new_tab()\

    def close_current_tab(self, index):
        if self.tabs.count() < 2:
            return
        self.tabs.removeTab(index)


    def openFile(self):
        options = qtw.QFileDialog.Options()
        filenames, _ = qtw.QFileDialog.getOpenFileNames(
            self, 'Open a file', '',
            'All Files (*);;Python Files (*.py);;Text Files (*.txt)',
            options=options
        )
        if filenames:
            for filename in filenames:
                with open(filename, 'r') as file_o:
                    content = file_o.read()
                    editor = qtw.QTextEdit()   # construct new text edit widget
                    self.tabs.addTab(editor, str(filename))   # use that widget as the new tab
                    editor.setPlainText(content)  # set the contents of the file as the text


    def closeTab(self, index):
        tab = self.tabs.widget(index)
        tab.deleteLater()
        self.tabs.removeTab(index)


if __name__ == "__main__":
    app = qtw.QApplication(sys.argv)
    main = MainWindow()
    main.show()
    sys.exit(app.exec_())
  • Related