How to populate a QTextEdit, that is inside a QTabWidget, by opening a text file? [pyqt5, python]
Question:
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...")
Answers:
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_())
EDIT (8/25/2022): i merged the solution above with the following functionalities:
- new tab
- close tab
- save file
(since these things are implicitly needed for what the question is trying to achieve)
- open tab
(modified the openFile
method to match with the new changes. thanks to the insightful comments by the man, the myth, the legend himself, Alexander
the improvements start with these lines of codes:
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.current_editor = self.create_editor() # declares a variable for the create_editor method
self.text_editors = [] # an array that stores the indexes of newly created QTextEdit object
""" removed codes that are not part of the explanation"""
self.tabs.tabBarDoubleClicked.connect(self.tab_open_doubleclick)
self.tabs.tabCloseRequested.connect(self.remove_editor)
self.tabs.currentChanged.connect(self.change_text_editor) # whenever a different tab is clicked the change_text_editor method is called
self.setCentralWidget(self.tabs)
this method creates and returns a new QTextEdit
widget (or object)
def create_editor(self):
textedit = qtw.QTextEdit()
return textedit
this method returns the index of the of the currently selected tab’s QTextEdit
stored in the self.text_editors
array
def change_text_editor(self, index):
if index < len(self.text_editors):
self.current_editor = self.text_editors[index]
now, since we are able to keep tabs on exactly which QTextEdit
is currently selected at a given time. we would now be capable to do whatever we want with it by just calling self.current_editor
, as if it was just some normal QTextEdit
without the tab functionality.
here is the full runnable code:
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.current_editor = self.create_editor() # declares a variable for the create_editor method
self.text_editors = [] # an array that stores the indexes of newly created tabs
self.statusbar = self.statusBar()
self.statusbar.showMessage('Ready')
self.setWindowTitle("Notepad with tabs")
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.remove_editor)
self.tabs.currentChanged.connect(self.change_text_editor) # whenever a different tab is clicked the change_text_editor method is called
self.setCentralWidget(self.tabs)
self.newFile()
self.menuBar_new()
self.menuBar_open()
self.menuBar_close()
self.menuBar_save()
self.menuBar_exit_program()
self.initUI()
def initUI(self):
menubar = self.menuBar()
file_menu = menubar.addMenu('File')
file_menu.addAction(self.new_file)
file_menu.addAction(self.open_file)
file_menu.addAction(self.save_file)
file_menu.addSeparator()
file_menu.addAction(self.exit_program)
def create_editor(self):
textedit = qtw.QTextEdit()
return textedit
def change_text_editor(self, index):
if index < len(self.text_editors):
self.current_editor = self.text_editors[index]
def menuBar_new(self):
self.new_file = qtw.QAction(qtg.QIcon(':/images/folder.png'),"New", self)
self.new_file.setShortcut('Ctrl+N')
self.new_file.setStatusTip('New file')
self.new_file.triggered.connect(self.newFile)
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_save(self):
self.save_file = qtw.QAction(qtg.QIcon(':/images/folder.png'),"Save", self)
self.save_file.setShortcut('Ctrl+S')
self.save_file.setStatusTip('Save a file')
self.save_file.triggered.connect(self.saveFile)
def menuBar_close(self):
close_tab = qtw.QShortcut(qtg.QKeySequence("Ctrl+W"), self)
close_tab.activated.connect(lambda:self.remove_editor(self.tabs.currentIndex()))
def menuBar_exit_program(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 remove_editor(self, index):
if self.tabs.count() < 2:
return
self.tabs.removeTab(index)
if index < len(self.text_editors):
del self.text_editors[index]
def create_editor(self):
text_editor = qtw.QTextEdit()
return text_editor
def change_text_editor(self, index):
if index < len(self.text_editors):
self.current_editor = self.text_editors[index]
# Input Functions
def newFile(self, checked = False, title = "Untitled.txt"):
self.current_editor = self.create_editor()
self.text_editors.append(self.current_editor)
self.tabs.addTab(self.current_editor, title)
self.tabs.setCurrentWidget(self.current_editor)
def tab_open_doubleclick(self, index):
if index == -1:
self.newFile()
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.current_editor = self.create_editor() # similar to what the newFile method is doing
# editor = qtw.QTextEdit() # construct new text edit widget
currentIndex = self.tabs.addTab(self.current_editor, str(filename)) # use that widget as the new tab
self.current_editor.setPlainText(content) # set the contents of the file as the text
self.tabs.setCurrentIndex(currentIndex) # make current opened tab be on focus
def saveFile(self):
text = self.current_editor.toPlainText()
filename, _ = qtw.QFileDialog.getSaveFileName(self, 'Save file', None, 'Text files(*.txt)')
if filename:
with open(filename, "w") as handle:
handle.write(text)
print(self.tabs.currentIndex())
print(str(filename))
self.tabs.setTabText(self.tabs.currentIndex(), str(filename)) # renames the current tab with the filename
self.statusBar().showMessage(f"Saved to {filename}")
if __name__ == "__main__":
app = qtw.QApplication(sys.argv)
main = MainWindow()
main.resize(650,500)
main.setMinimumSize(550,450)
main.show()
sys.exit(app.exec_())
hope it helps 🙂 thanks again to mr. Alexander for helping me with the codes. i would have never have figured it out without his insightful help
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...")
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_())
EDIT (8/25/2022): i merged the solution above with the following functionalities:
- new tab
- close tab
- save file
(since these things are implicitly needed for what the question is trying to achieve)
- open tab
(modified the openFile
method to match with the new changes. thanks to the insightful comments by the man, the myth, the legend himself, Alexander
the improvements start with these lines of codes:
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.current_editor = self.create_editor() # declares a variable for the create_editor method
self.text_editors = [] # an array that stores the indexes of newly created QTextEdit object
""" removed codes that are not part of the explanation"""
self.tabs.tabBarDoubleClicked.connect(self.tab_open_doubleclick)
self.tabs.tabCloseRequested.connect(self.remove_editor)
self.tabs.currentChanged.connect(self.change_text_editor) # whenever a different tab is clicked the change_text_editor method is called
self.setCentralWidget(self.tabs)
this method creates and returns a new QTextEdit
widget (or object)
def create_editor(self):
textedit = qtw.QTextEdit()
return textedit
this method returns the index of the of the currently selected tab’s QTextEdit
stored in the self.text_editors
array
def change_text_editor(self, index):
if index < len(self.text_editors):
self.current_editor = self.text_editors[index]
now, since we are able to keep tabs on exactly which QTextEdit
is currently selected at a given time. we would now be capable to do whatever we want with it by just calling self.current_editor
, as if it was just some normal QTextEdit
without the tab functionality.
here is the full runnable code:
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.current_editor = self.create_editor() # declares a variable for the create_editor method
self.text_editors = [] # an array that stores the indexes of newly created tabs
self.statusbar = self.statusBar()
self.statusbar.showMessage('Ready')
self.setWindowTitle("Notepad with tabs")
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.remove_editor)
self.tabs.currentChanged.connect(self.change_text_editor) # whenever a different tab is clicked the change_text_editor method is called
self.setCentralWidget(self.tabs)
self.newFile()
self.menuBar_new()
self.menuBar_open()
self.menuBar_close()
self.menuBar_save()
self.menuBar_exit_program()
self.initUI()
def initUI(self):
menubar = self.menuBar()
file_menu = menubar.addMenu('File')
file_menu.addAction(self.new_file)
file_menu.addAction(self.open_file)
file_menu.addAction(self.save_file)
file_menu.addSeparator()
file_menu.addAction(self.exit_program)
def create_editor(self):
textedit = qtw.QTextEdit()
return textedit
def change_text_editor(self, index):
if index < len(self.text_editors):
self.current_editor = self.text_editors[index]
def menuBar_new(self):
self.new_file = qtw.QAction(qtg.QIcon(':/images/folder.png'),"New", self)
self.new_file.setShortcut('Ctrl+N')
self.new_file.setStatusTip('New file')
self.new_file.triggered.connect(self.newFile)
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_save(self):
self.save_file = qtw.QAction(qtg.QIcon(':/images/folder.png'),"Save", self)
self.save_file.setShortcut('Ctrl+S')
self.save_file.setStatusTip('Save a file')
self.save_file.triggered.connect(self.saveFile)
def menuBar_close(self):
close_tab = qtw.QShortcut(qtg.QKeySequence("Ctrl+W"), self)
close_tab.activated.connect(lambda:self.remove_editor(self.tabs.currentIndex()))
def menuBar_exit_program(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 remove_editor(self, index):
if self.tabs.count() < 2:
return
self.tabs.removeTab(index)
if index < len(self.text_editors):
del self.text_editors[index]
def create_editor(self):
text_editor = qtw.QTextEdit()
return text_editor
def change_text_editor(self, index):
if index < len(self.text_editors):
self.current_editor = self.text_editors[index]
# Input Functions
def newFile(self, checked = False, title = "Untitled.txt"):
self.current_editor = self.create_editor()
self.text_editors.append(self.current_editor)
self.tabs.addTab(self.current_editor, title)
self.tabs.setCurrentWidget(self.current_editor)
def tab_open_doubleclick(self, index):
if index == -1:
self.newFile()
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.current_editor = self.create_editor() # similar to what the newFile method is doing
# editor = qtw.QTextEdit() # construct new text edit widget
currentIndex = self.tabs.addTab(self.current_editor, str(filename)) # use that widget as the new tab
self.current_editor.setPlainText(content) # set the contents of the file as the text
self.tabs.setCurrentIndex(currentIndex) # make current opened tab be on focus
def saveFile(self):
text = self.current_editor.toPlainText()
filename, _ = qtw.QFileDialog.getSaveFileName(self, 'Save file', None, 'Text files(*.txt)')
if filename:
with open(filename, "w") as handle:
handle.write(text)
print(self.tabs.currentIndex())
print(str(filename))
self.tabs.setTabText(self.tabs.currentIndex(), str(filename)) # renames the current tab with the filename
self.statusBar().showMessage(f"Saved to {filename}")
if __name__ == "__main__":
app = qtw.QApplication(sys.argv)
main = MainWindow()
main.resize(650,500)
main.setMinimumSize(550,450)
main.show()
sys.exit(app.exec_())
hope it helps 🙂 thanks again to mr. Alexander for helping me with the codes. i would have never have figured it out without his insightful help