PyXLL The Python Excel Add-In
  • Product
    • Features
    • Get Started
    • Request Demo
    • Download
  • Pricing
  • Resources
    • Documentation
    • Blog
    • Videos
    • FAQ
    • Learn Python
    • Customer Portal
    • About Us
  • Support
    • Documentation
    • Videos
    • FAQ
    • Contact Us
  • Contact Us
Table of Contents
  • PyXLL Documentation
  • Introduction to PyXLL
  • User Guide
    • Installing PyXLL
    • Configuring PyXLL
    • Worksheet Functions
    • Macro Functions
    • Real Time Data
    • Cell Formatting
    • Charts and Plotting
    • Custom Task Panes
    • ActiveX Controls
      • PySide and PyQt
      • wxPython
      • Tkinter
      • Other UI Toolkits
      • Resizing ActiveX Controls
      • Other Considerations
    • Using Pandas in Excel
    • Customizing the Ribbon
    • Context Menu Functions
    • Working with Tables
    • Python as a VBA Replacement
    • Menu Functions
    • Reloading and Rebinding
    • Error Handling
    • Deploying your add-in
    • Workbook Metadata
  • Video Guides and Tutorials
  • API Reference
  • What’s new in PyXLL 5
  • Changelog
Close

wxPython¶

wxPython is a Python packages that wraps the UI toolkit wxWindows.

This document is not a guide to use wxPython or wxWindows. It is only intended to instruct you on how to use wxPython with the Custom Task Pane feature of PyXLL. You should refer to the relevant package documentation for details of how to use wxPython and wxWindows.

User interfaces developed using wxWindows can be embedded as ActiveX controls directly on the Excel worksheet. If instead you want your controls to appear in a docked or floating window, see Custom Task Panes.

Both wxWindows can be installed using pip or conda, for example:

> pip install wxpython
# or
> conda install wxpython

You should install it using pip or conda and not both.

You can find more information about wxPython on the website https://www.wxpython.org/.

A wxPython frame in an Excel ActiveX control

Creating a wx Frame¶

Two of the main classes we’ll use in wxPython are the wx.Frame and wx.Panel classes.

A wx.Frame is the main window type, and it’s this that you’ll create to contain your user interface that will be embedded into Excel as an ActiveX control. Frames typically host a single wx.Panel which is where all the controls that make up your user interface will be placed.

The following code demonstrates how to create simple wx.Frame and corresponding wx.Panel. If you run this code as a Python script then you will see the frame being shown.

import wx

class ExamplePanel(wx.Panel):

    def __init__(self, parent):
        super().__init__(parent=parent)

        # Create a sizer that will lay everything out in the panel.
        # A BoxSizer can arrange controls horizontally or vertically.
        sizer = wx.BoxSizer(orient=wx.VERTICAL)

        # Create a TextCtrl control and add it to the layout
        self.text_ctrl = wx.TextCtrl(self)
        sizer.Add(self.text_ctrl, flag=wx.ALL | wx.EXPAND, border=10)
        sizer.AddSpacer(20)

        # Create a StaticText control and add it to the layout
        self.static_text = wx.StaticText(self)
        sizer.Add(self.static_text, flag=wx.ALL | wx.EXPAND, border=10)

        # Connect the 'EVT_TEXT' event to our 'onText' method
        self.text_ctrl.Bind(wx.EVT_TEXT, self.onText)

        # Set the sizer for this panel and layout the controls
        self.SetSizer(sizer)
        self.Layout()

    def onText(self, event):
        """Called when the TextCtrl's text is changed"""
        # Set the text from the event onto the static_text control
        text = event.GetString()
        self.static_text.SetLabel(text)

class ExampleFrame(wx.Frame):

    def __init__(self):
        super().__init__(parent=None)

        # Create the panel that contains the controls for this frame
        self.panel = ExamplePanel(parent=self)


if __name__ == "__main__":
    # Create the wx Application object
    app = wx.App()

    # Construct our example Frame and show it
    frame = ExampleFrame()
    frame.Show()

    # Run the application's main event loop
    app.MainLoop()

When you run this code you will see our example frame being display, and as you enter text into the text control the static text below will be updated.

A wxPython example frame

Next we’ll see how we can use this frame in Excel.

Creating an ActiveX control from a wx.Frame¶

To show a wx.Frame in Excel using PyXLL as an ActiveX control we use the create_activex_control function.

As above, before we can create the frame we have to make sure the wx.App application object has been initialized. Unlike the above script, our function may be called many times and so we don’t want to create a new application each time and so we check to see if one already exists.

The wx.App object must still exist when we call create_activex_control. If it has gone out of scope and been released then it will cause problems later so always make sure to keep a reference to it.

We can create the ActiveX control from many different places, but usually it will be from a ribbon function, or a menu function, or a worksheet function

The following code shows how we would create a ActiveX control from an Excel menu function, using the ExampleFrame control from the example above.

from pyxll import xl_menu, create_activex_control
import wx

@xl_menu("Wx ActiveX Control")
def wx_activex_control():
    # Before we can create a wx.Frame the wx.App must have been initialized.
    # Make sure we keep a reference to this until create_activex_control is called.
    app = wx.App.Get()
    if app is None:
        app = wx.App()

    # Create our example frame from the code above
    frame = ExampleFrame()

    # Use PyXLL's 'create_activex_control' function to create the ActiveX control.
    create_activex_control(frame, width=400, height=400)

When we add this code to PyXLL and reload the new menu function “Wx ActiveX Control” will be available, and when that menu function is run the ExampleFrame is opened as an ActiveX control in Excel.

The optional parameters to create_activex_control can be used to set the size, position, and what sheet the control is created on.

A Python Wx frame in an Excel ActiveX control

To move or resize the ActiveX control you first need to enable Design Mode.

To enable Design Mode, go to the Developer tab in the Excel ribbon and select Design Mode. Whilst in Design Mode a bitmap preview will be displayed instead of the web control. You can now move and resize this shape. There may be some lag between resizing the preview image and the preview image updating.

To return to the interactive web widget, unselect Design Mode.

Entering design mode

See the API reference for create_activex_control for more details.

« PySide and PyQt
Tkinter »
  • Home
  • Product
  • Features
  • Documentation
  • Download
  • Pricing
  • Support
  • Documentation
  • Videos
  • FAQ
  • Learn Python
  • Contact Us
  • About
  • About Us
  • Legal
  • Blog
© Copyright PyXLL Ltd