Create simple-PyQt6-gui.py
This commit is contained in:
@@ -0,0 +1,218 @@
|
||||
from PyQt6.QtWidgets import QApplication, QMainWindow, QTextEdit, QMenuBar
|
||||
from PyQt6.QtWidgets import QTabWidget, QVBoxLayout, QWidget, QFileDialog, QTabBar
|
||||
from PyQt6.QtGui import QAction
|
||||
from PyQt6.QtCore import Qt, QEvent
|
||||
import os, sys
|
||||
|
||||
application_name = "MSG Viewer"
|
||||
|
||||
"""
|
||||
This is simple PyQt6 interface to open text files in tabs.
|
||||
"""
|
||||
|
||||
class TabContent(QWidget):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
# Create the text editor for each tab
|
||||
self.text_area = QTextEdit(self)
|
||||
self.text_area.setObjectName("Container")
|
||||
self.text_area.setStyleSheet(
|
||||
"""#Container {
|
||||
background: qlineargradient(x1:0 y1:0, x2:1 y2:1, stop:0 #051c2a stop:1 #44315f);
|
||||
border-radius: 5px;
|
||||
}"""
|
||||
)
|
||||
layout = QVBoxLayout(self)
|
||||
layout.addWidget(self.text_area)
|
||||
self.setLayout(layout)
|
||||
|
||||
def setText(self, text):
|
||||
self.text_area.setPlainText(text)
|
||||
|
||||
def getText(self):
|
||||
return self.text_area.toPlainText()
|
||||
|
||||
def setReadOnly(self, readonly):
|
||||
self.text_area.setReadOnly(readonly)
|
||||
|
||||
def isReadOnly(self):
|
||||
return self.text_area.isReadOnly()
|
||||
|
||||
|
||||
class AppMainWindow(QMainWindow):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.initUI()
|
||||
|
||||
def initUI(self):
|
||||
# Create the tab widget that will hold the tabs
|
||||
self.tabs = QTabWidget(self)
|
||||
self.tabs.setTabsClosable(True) # Enable the close button on tabs
|
||||
self.tabs.setMovable(True) # Enable the moving (reordering) of tabs
|
||||
self.tabs.tabCloseRequested.connect(self.close_tab) # Connect to tab close event
|
||||
self.tabs.currentChanged.connect(self.on_tab_changed) # Listen for tab change event
|
||||
self.setCentralWidget(self.tabs)
|
||||
|
||||
# Enable middle-click closing for tabs
|
||||
self.tabs.tabBar().installEventFilter(self)
|
||||
|
||||
# Set the window title and size
|
||||
self.setWindowTitle(application_name)
|
||||
self.setGeometry(100, 100, 800, 600)
|
||||
|
||||
# Create the menu bar with toolbar buttons
|
||||
self.createToolbar()
|
||||
|
||||
def createToolbar(self):
|
||||
# Create a menu bar
|
||||
self.menuBar = QMenuBar()
|
||||
self.setMenuBar(self.menuBar)
|
||||
|
||||
# Action to open a file
|
||||
self.open_btn = QAction("Open", self)
|
||||
self.open_btn.triggered.connect(self.open_file)
|
||||
self.open_btn.setStatusTip("Open MSG file")
|
||||
self.menuBar.addAction(self.open_btn)
|
||||
|
||||
# Action to toggle between Edit and Read-Only modes
|
||||
self.edit_btn = QAction("ReadOnly", self) # Default to "ReadOnly"
|
||||
self.edit_btn.setStatusTip("Make message read-only")
|
||||
self.edit_btn.triggered.connect(self.edit_file)
|
||||
self.edit_btn.setVisible(False)
|
||||
self.menuBar.addAction(self.edit_btn)
|
||||
|
||||
# Action to save the file
|
||||
self.save_btn = QAction("Extract", self)
|
||||
self.save_btn.setStatusTip("Save current file")
|
||||
self.save_btn.triggered.connect(self.save_file)
|
||||
self.save_btn.setVisible(False)
|
||||
self.menuBar.addAction(self.save_btn)
|
||||
|
||||
self.menuBar.setStyleSheet("""
|
||||
QMenuBar {
|
||||
background-color: #9a9c9a;
|
||||
border-bottom: 1px solid #000000;
|
||||
padding: 2px;
|
||||
}
|
||||
QMenuBar::item {
|
||||
background-color: #292626;
|
||||
padding: 5px 10px;
|
||||
border: 1px solid transparent;
|
||||
margin: 2px;
|
||||
font-weight: bold;
|
||||
}
|
||||
QMenuBar::item:selected {
|
||||
background-color: #d0d0d0;
|
||||
border: 1px solid #999999;
|
||||
color: black;
|
||||
border-radius: 3px;
|
||||
}
|
||||
QMenuBar::item:pressed {
|
||||
background-color: #b0b0b0;
|
||||
}
|
||||
""")
|
||||
|
||||
def open_file(self):
|
||||
# Open a file using a file dialog
|
||||
file, _ = QFileDialog.getOpenFileName(
|
||||
self,
|
||||
"Open File",
|
||||
"",
|
||||
"All Files (*);;HTML Files (*.html);;Text Files (*.txt)"
|
||||
)
|
||||
if file:
|
||||
try:
|
||||
# Read the content of the file
|
||||
with open(file, 'r', encoding="utf-8") as f:
|
||||
file_content = f.read()
|
||||
|
||||
# Create a new tab
|
||||
tab_content = TabContent()
|
||||
tab_content.setText(file_content)
|
||||
tab_index = self.tabs.addTab(tab_content, os.path.basename(file))
|
||||
self.tabs.setCurrentIndex(tab_index)
|
||||
|
||||
# Enable save and edit actions
|
||||
self.save_btn.setVisible(True)
|
||||
self.edit_btn.setVisible(True)
|
||||
|
||||
# Set the editor to Read-Only mode by default
|
||||
tab_content.setReadOnly(True)
|
||||
self.edit_btn.setText("Edit")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error opening file: {e}")
|
||||
|
||||
def edit_file(self):
|
||||
# Get the current active tab
|
||||
current_tab = self.tabs.currentWidget()
|
||||
|
||||
# Toggle between Edit and ReadOnly modes
|
||||
if self.edit_btn.text() == "Edit":
|
||||
current_tab.setReadOnly(False) # Allow editing
|
||||
self.edit_btn.setText("ReadOnly")
|
||||
self.edit_btn.setStatusTip("Make message read-only")
|
||||
else:
|
||||
current_tab.setReadOnly(True) # Make read-only
|
||||
self.edit_btn.setText("Edit")
|
||||
self.edit_btn.setStatusTip("Allows Editing of the message")
|
||||
|
||||
def save_file(self):
|
||||
# Get the current active tab
|
||||
current_tab = self.tabs.currentWidget()
|
||||
|
||||
# Open a file dialog to save the file
|
||||
file, _ = QFileDialog.getSaveFileName(
|
||||
self,
|
||||
"Save File",
|
||||
"",
|
||||
"All Files (*);;HTML Files (*.html);;Text Files (*.txt)"
|
||||
)
|
||||
if file:
|
||||
try:
|
||||
# Save the content of the text area to the file
|
||||
with open(file, 'w', encoding="utf-8") as f:
|
||||
f.write(current_tab.getText())
|
||||
self.setWindowTitle(f"{application_name} - {os.path.basename(file)}")
|
||||
except Exception as e:
|
||||
print(f"Error saving file: {e}")
|
||||
|
||||
def close_tab(self, index):
|
||||
# This function will be triggered when a user clicks on the "X" button of a tab
|
||||
widget = self.tabs.widget(index)
|
||||
if widget:
|
||||
self.tabs.removeTab(index)
|
||||
widget.deleteLater() # Free up the memory of the widget
|
||||
|
||||
def on_tab_changed(self, index):
|
||||
# This function is called when the user switches between tabs
|
||||
current_tab = self.tabs.widget(index)
|
||||
if current_tab:
|
||||
# Set the "Edit/ReadOnly" button text based on the current tab's state
|
||||
if current_tab.isReadOnly():
|
||||
self.edit_btn.setText("Edit")
|
||||
self.edit_btn.setStatusTip("Allows Editing of the message")
|
||||
else:
|
||||
self.edit_btn.setText("ReadOnly")
|
||||
self.edit_btn.setStatusTip("Make message read-only")
|
||||
|
||||
def eventFilter(self, source, event):
|
||||
# Listen for middle mouse button clicks to close tabs
|
||||
if source == self.tabs.tabBar() and event.type() == QEvent.Type.MouseButtonPress:
|
||||
if event.button() == Qt.MouseButton.MiddleButton:
|
||||
index = self.tabs.tabBar().tabAt(event.pos())
|
||||
if index != -1:
|
||||
self.tabs.removeTab(index)
|
||||
return True
|
||||
return super().eventFilter(source, event)
|
||||
|
||||
|
||||
def main():
|
||||
app = QApplication(sys.argv)
|
||||
app.setStyle("Fusion")
|
||||
app_window = AppMainWindow()
|
||||
app_window.show()
|
||||
sys.exit(app.exec())
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user