Today we’re going to talk about something that will make your Python apps look like they have a personality. That’s right, I’m talking about logging to a Qt GUI for all you fancy pants out there who want their code to be more than just a bunch of text on the screen.
First, let’s get our hands dirty and install some packages we need. If you haven’t already done so, make sure you have pip installed (if not, go ahead and do that now). Then, open up your terminal or command prompt and type:
# This script installs the necessary packages for using PyQt5 and python-qt-binding.
# First, we need to check if pip is installed. If not, we will install it.
# The command "which" checks if a program is installed and returns its path.
# The "if" statement checks if the return value is empty, indicating that pip is not installed.
# If it is not empty, the "then" block will not be executed.
if [ -z "$(which pip)" ]; then
# The "echo" command prints a message to the terminal.
echo "Pip is not installed. Installing now..."
# The "sudo" command allows us to run a command with root privileges.
# The "apt-get" command is used to install packages on Debian-based systems.
# The "-y" flag automatically answers "yes" to any prompts during installation.
sudo apt-get install -y python-pip
fi
# Now that we have pip installed, we can use it to install the necessary packages.
# The "pip install" command is used to install packages from the Python Package Index (PyPI).
# The "PyQt5" package is a Python binding for the Qt application framework.
# The "python-qt-binding" package provides additional Qt bindings for Python.
pip install PyQt5
pip install python-qt-binding
These packages will give us the ability to create a GUI using Qt and bind it with Python. Once they’re installed, let’s get started on our code!
First, we need to import some libraries:
# Import the logging library to enable logging functionality
import logging
# Import the necessary packages from PyQt5 to create a GUI
from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit, QVBoxLayout
# Import the Qt library from python_qt_binding to access Qt functionalities
from python_qt_binding.QtCore import Qt
# Create a QApplication instance to manage the GUI application
app = QApplication([])
# Create a QMainWindow instance to serve as the main window of the GUI
window = QMainWindow()
# Create a QTextEdit instance to display text in the GUI
text_edit = QTextEdit()
# Create a QVBoxLayout instance to organize the layout of the GUI
layout = QVBoxLayout()
# Set the alignment of the layout to be centered
layout.setAlignment(Qt.AlignCenter)
# Add the text_edit widget to the layout
layout.addWidget(text_edit)
# Set the layout of the main window to be the layout we created
window.setLayout(layout)
# Set the title of the main window
window.setWindowTitle("My GUI")
# Show the main window
window.show()
# Start the event loop of the application
app.exec_()
# Close the application once the event loop is finished
app.quit()
We’re going to use the `logging` library for our actual logging functionality and some of the other libraries we imported will help us create a GUI using PyQt5.
Next, let’s set up our logger:
# Import the logging library
import logging
# Set up the logger with the name of the current module
logger = logging.getLogger(__name__)
# Create a handler to handle the logging output
handler = logging.StreamHandler()
# Create a formatter to format the logging output
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
# Set the formatter for the handler
handler.setFormatter(formatter)
# Add the handler to the logger
logger.addHandler(handler)
# The logger is now set up and ready to be used for logging purposes.
We’re using the `getLogger(__name__)` function to get a logger for our current module (in this case, it would be whatever file we have this code in). We then create a stream handler and set up a formatter that will display the date/time, log level, and message. Finally, we add the handler to our logger.
Now let’s move on to creating our GUI:
# Import necessary libraries
import sys
from PyQt5.QtWidgets import QMainWindow, QTextEdit, QVBoxLayout, QWidget, QApplication
# Create a class for our main window
class MainWindow(QMainWindow):
def __init__(self):
super().__init__() # Call the parent class constructor
# Create a text edit widget
self.text_edit = QTextEdit()
# Create a layout and add the text edit widget to it
layout = QVBoxLayout()
layout.addWidget(self.text_edit)
# Create a widget and set the layout to it
widget = QWidget()
widget.setLayout(layout)
# Set the central widget of the main window to our widget
self.setCentralWidget(widget)
# Set up our logger to display in the text edit
handler = logging.StreamHandler(sys.stdout) # Create a stream handler to display logs in the console
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') # Create a formatter to display date/time, log level, and message
handler.setFormatter(formatter) # Set the formatter to the handler
self.logger = logging.getLogger(__name__) # Get a logger for our current module
self.logger.addHandler(handler) # Add the handler to our logger
# Show the window and start the event loop
self.show()
sys.exit(app.exec_()) # Start the event loop for the application
# Create an instance of the application
app = QApplication(sys.argv)
# Create an instance of our main window
window = MainWindow()
# Start the application
sys.exit(app.exec_())
We’re creating a new class called `MainWindow`, which is going to be our GUI. We create a text edit widget, add it to a layout, and set that as our central widget. Then we set up the logger again (this time with the stream handler pointing to sys.stdout) so that any log messages will display in the text edit.
Finally, let’s run this bad boy:
# Import necessary libraries
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
# Define main function
def main():
# Create an instance of QApplication
app = QApplication(sys.argv)
# Create an instance of MainWindow class
window = MainWindow()
# Execute the application and exit when closed
sys.exit(app.exec_())
# Check if the script is being run directly
if __name__ == '__main__':
# Call the main function
main()
# Define MainWindow class
class MainWindow(QMainWindow):
# Constructor
def __init__(self):
# Call the parent constructor
super().__init__()
# Create a text edit widget
text_edit = QTextEdit()
# Add the text edit widget to a layout
layout = QVBoxLayout()
layout.addWidget(text_edit)
# Set the layout as the central widget
self.setCentralWidget(layout)
# Set up the logger with a stream handler pointing to sys.stdout
self.setup_logger()
# Show the main window
self.show()
# Function to set up the logger
def setup_logger(self):
# Import necessary library
import logging
# Create a logger
logger = logging.getLogger()
# Set the logger level to INFO
logger.setLevel(logging.INFO)
# Create a stream handler pointing to sys.stdout
stream_handler = logging.StreamHandler(sys.stdout)
# Add the stream handler to the logger
logger.addHandler(stream_handler)
# Run the application
main()
We create a new instance of our `MainWindow` class, set it as the main application using Qt’s `QApplication`, and run the event loop. And that’s it! You should now have a GUI with your log messages displayed in real-time.
Give it a try !