SoFunction
Updated on 2025-04-16

Brief analysis of how to build a desktop image browser using Python

In this blog, we will dig into a desktop image browser application built using Python and wxPython. The application provides a graphical user interface (GUI) through wxPython and displays pictures in the browser in conjunction with a local web server. We will break down the code one by one, analyze its components, and explore how it works.

Application Overview

The application is designed to allow users to launch a web-based interface through the desktop GUI to browse pictures in local folders. Here is an overview of its main functions:

  • Graphic interface: A window built using wxPython, providing simple buttons for starting the image browser and exiting the application.
  • Web server: Run a local HTTP server through Python modules, providing HTML-based image display page.
  • Image display: The web interface allows users to select folders, view pictures in the form of slides, and supports navigation through buttons or keyboard arrow keys.
  • Cross-platform support: Applications support running as scripts or packaged as executables (for example using PyInstaller).

The code integrates multiple Python libraries, including wx (for GUI), socketserver (for web server), webbrowser (for browser opening), and threading (for concurrent processing).

Code Analysis

Let's analyze the key components of the code one by one to understand how they work together.

1. Constants and imports

The code first defines the constants and imports the necessary modules:

import os
import sys
import time
import webbrowser
import threading
import 
import socketserver
import wx
from pathlib import Path
 
APP_NAME = "Picture Browser"
PORT = 8080
SERVER_THREAD = None
SERVER_STARTED = ()
HTML_FILENAME = "image_browser.html"
  • Constant: APP_NAME defines the application name ("Image Browser"), PORT sets the default server port, HTML_FILENAME specifies the HTML file for the image to display.
  • Import: Use wx (GUI), socketserver (Web server), threading (concurrency) and other libraries.
  • Thread Event: SERVER_STARTED is an object that marks the server startup completion to ensure that the browser is opened after the server startup.

2. HTML file management

The application dynamically manages an HTML file (image_browser.html) to define a web-based image display page.

get_html_path()
def get_html_path():
    if getattr(sys, 'frozen', False):
        app_dir = Path(sys._MEIPASS)
    else:
        app_dir = Path(((__file__)))
    
    html_path = app_dir / HTML_FILENAME
    
    if not html_path.exists():
        create_html_file(html_path)
    
    return html_path

This function determines the path to the HTML file and is compatible with the executable file that the script runs and packages. If the HTML file does not exist, create_html_file() is called to generate the file.

create_html_file()
def create_html_file(file_path):
    html_content = """<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Image Browser</title>
    <style>
        /* CSS style for picture display */
    </style>
</head>
<body>
    <h1>Image Browser</h1>
    <div class="container">
        <div class="file-selection">
            <input type="file"  webkitdirectory directory multiple />
            <label for="folder-input">Select a folder</label>
        </div>
        <div class="gallery" >
            <div class="no-images">Please select a folder containing pictures</div>
        </div>
        <div class="image-name" ></div>
        <div class="navigation">
            <button class="nav-btn"  disabled>Previous</button>
            <button class="nav-btn"  disabled>Next</button>
        </div>
        <div class="image-counter" >0/0</div>
    </div>
    <script>
        /* JavaScript logic for image display */
    </script>
</body>
</html>"""
    with open(file_path, 'w', encoding='utf-8') as f:
        (html_content)

This function generates an HTML file containing the following content:

  • HTML structure: including folder selection input box, image display area, navigation buttons and counters.
  • CSS style: Provides a neat and responsive layout that supports smooth transitions and hover effects.
  • JavaScript logic: handles folder selection, filters picture files, displays pictures, and supports navigation through buttons or keyboard arrow keys.

JavaScript uses the FileReader API to load images as Data URLs to avoid server-side file access and achieve sliding display effect through CSS transformation.

3. HTTP server

The application runs a local HTTP server that serves HTML files and images.

SimpleHTTPRequestHandler
class SimpleHTTPRequestHandler():
    def __init__(self, *args, **kwargs):
        directory = str(get_html_path().parent)
        super().__init__(*args, directory=directory, **kwargs)
    
    def log_message(self, format, *args):
        pass

This custom processor sets the server root directory to the folder where the HTML files reside and disables log output to keep the console tidy.

start_server()
def start_server():
    global PORT
    global SERVER_STARTED
    
    handler = SimpleHTTPRequestHandler
    
    while True:
        try:
            with (("localhost", PORT), handler) as httpd:
                print(f"The server is started http://localhost:{PORT}")
                SERVER_STARTED.set()
                httpd.serve_forever()
            break
        except OSError as e:
            print(f"port {PORT} Occupated,尝试下一个port...")
            PORT += 1
            if PORT > 8100:
                print("Available port cannot be found")
                return

This function starts the server and increments the port number if the default port (8080) is occupied until the available port is found (upper limit is 8100). After the server starts, set the SERVER_STARTED event.

4. Browser integration

The open_browser() function ensures that the image display page is open in the user's default browser:

def open_browser():
    if SERVER_STARTED.wait(5):
        url = f"http://localhost:{PORT}/{HTML_FILENAME}"
        print(f"Open a browser:{url}")
        try:
            (url)
        except Exception as e:
            print(f"Open a browser出错: {e}")
            (f"无法自动Open a browser,Please visit manually:\n{url}", 
                        "Open a browser失败", 
                         | wx.ICON_INFORMATION)
    else:
        print("Server startup timeout")
        ("The server failed to start, please try again", 
                    "mistake", 
                     | wx.ICON_ERROR)

This function waits up to 5 seconds to ensure the server starts, and then opens the URL. If the browser cannot open, a message box containing the URL is displayed for manual access by the user.

5. wxPython graphical interface

The graphical interface is built using wxPython to provide a native desktop interactive experience.

ImageBrowserApp
class ImageBrowserApp():
    def OnInit(self):
         = ImageBrowserFrame(None, title=APP_NAME)
        ()
        return True

This class initializes the wxPython application and creates the main window.

ImageBrowserFrame
class ImageBrowserFrame():
    def __init__(self, parent, title):
        super().__init__(parent, title=title, size=(400, 200))
        ()
         = (self)
        
        vbox = ()
        title_label = (, label=APP_NAME)
        title_font = (14, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
        title_label.SetFont(title_font)
        (title_label, 0,  | wx.ALIGN_CENTER, 20)
        
        self.status_text = (, label="Ready")
        (self.status_text, 0,  |  | wx.ALIGN_CENTER, 20)
        
        self.start_button = (, label="Open the image browser")
        (self.start_button, 0,  | , 20)
        self.start_button.Bind(wx.EVT_BUTTON, self.on_start)
        
        self.exit_button = (, label="quit")
        (self.exit_button, 0,  |  |  | , 20)
        self.exit_button.Bind(wx.EVT_BUTTON, self.on_exit)
        
        (vbox)
        (wx.EVT_CLOSE, self.on_exit)
        self.start_server()

The main window includes:

  • Title tag.
  • Status text (such as "ready").
  • The "Start" button is used to open the browser.
  • The "Exit" button is used to close the application.

The start_server() method runs the HTTP server in a separate thread and updates the status text when the server starts or fails.

Event handling

  • on_start(): Temporarily disable the start button, open the browser in the thread, and then re-enable the button.
  • on_exit(): Close the window and exit the application.

6. Main function

def main():
    app = ImageBrowserApp(False)
    ()
 
if __name__ == "__main__":
    main()

This function starts the wxPython application.

This is the end of this article about a brief analysis of how to build a desktop image browser using Python. For more related Python image browser content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!