Towards a Richer GUI: The TabControl, Splitter & the PictureBox

IronPython & Windows Forms, Part XI

Windows Forms

Note

This is part of a series of tutorials on using IronPython with Windows Forms.

 

 

Introduction

In this tutorial series so far we have covered some basic controls and background issues like setting attributes and GUI layout. In this article we'll be looking at a few more sophisticated controls.

Like much of the Windows Forms API, this can be done with remarkably little and clear code. It almost feels Pythonic. Wink

Unlike normal Python programming style, the dotnet convention is to create controls with an empty constructor and then set properties on the control.

Boiler Plate

Like previous entries we're going to need some boilerplate to create the form and start the application loop.

To refresh your memory we'll start with the boilerplate :

import clr
clr.AddReference('System.Windows.Forms')

from System.Windows.Forms import Application, Form

class MainForm(Form):

    def __init__(self):
        Form.__init__(self)
        self.Show()

Application.EnableVisualStyles()
form = MainForm()
Application.Run(form)

All this does is create and show a form.

The PictureBox

In order to illustrate the TabControl we'll display images in different tabs. To do this we'll use the PictureBox Class.

We'll need the PictureBoxSizeMode Enumeration, this tells the PictureBox how to position the image.

In order to provide the image, we'll need the Image Class and its FromFile method. The Image class lives in the System.Drawing assembly.

The bare code will look something like :

import clr
clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')

from System.Windows.Forms import PictureBox, PictureBoxSizeMode
from System.Drawing import Image

image = Image.FromFile(pathToFile)
pictureBox = PictureBox()
pictureBox.SizeMode = PictureBoxSizeMode.StretchImage
pictureBox.Image = image

We'll be using DockStyle.Fill to make the picturebox fill its parent control.

This makes the full code :

import clr
clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')

from System.Windows.Forms import (
    Application, DockStyle, Form, PictureBox, PictureBoxSizeMode
)
from System.Drawing import Image

pathToFile = 'images/greenlake.jpg'

class MainForm(Form):

    def __init__(self):
        Form.__init__(self)
        image = Image.FromFile(pathToFile)
        pictureBox = PictureBox()
        pictureBox.SizeMode = PictureBoxSizeMode.StretchImage
        pictureBox.Image = image
        pictureBox.Dock = DockStyle.Fill

        self.Controls.Add(pictureBox)

        self.Show()

Application.EnableVisualStyles()
form = MainForm()
Application.Run(form)

Using the greenlake image, this results in :

PictureBox on a Form

Because we set DockStyle.Fill and PictureBoxSizeMode.StretchImage resizing is handled automatically.

The TabControl

TabControls allow you to reduce the complexity of GUIs by dividing it into several pages that can be selected by clicking on the tabs.

The TabControl is the container into which you place multiple TabPages. The TabPage itself is an empty container control into which you can place more GUI components.

The order of the tab pages in the TabControl.TabPages collection reflects the order of tabs in the TabControl control. To change the order of tabs in the control, you must change their positions in the collection by removing them and inserting them at new indexes.

The tabs are part of the TabControl, but you set the text on them by setting the Text property on the TabPage.

The TabPages property is a TabPageCollection which has such useful methods as Add, Clear, Remove and Insert.

You set the location of the tabs using the Alignment Property on the TabControl and the TabAlignment enumeration.

Assuming we have already initialised a PictureBox, the code to create a TabControl and add a TabPage containing the image looks like this :

tabControl = TabControl()
tabControl.Dock = DockStyle.Fill
tabControl.Alignment = TabAlignment.Bottom

tabPage = TabPage()
tabPage.Text = 'SomeImage'
tabPage.Controls.Add(pictureBox)

tabControl.TabPages.Add(tabPage)

The SplitContainer

The SplitContainer is another control which, when used in the right place, can greatly augment an HCI.

A splitter divides an area of a GUI into two parts, with a draggable bar that divides them. It can be a vertical bar or a horizontal bar depending on the Orientation you set (Using the Orientation Enumeration).

You can set controls in the two panels it contains with the Panel1 and Panel2 properties.

We'll spice up the GUI in our example by having two tabcontrols dividedby the split container.

If we setup a method called setupPanel to add a TabControl to a panel, then setting up a splitter is very simple :

self.image1 = Image.FromFile(pathToFile1)
self.image2 = Image.FromFile(pathToFile2)

splitter = SplitContainer()
splitter.Orientation = Orientation.Vertical
splitter.Dock = DockStyle.Fill

self.setupPanel(splitter.Panel1, self.image1)
self.setupPanel(splitter.Panel2, self.image2)
self.Controls.Add(splitter)

Like any other control, we can handle events on the SplitContainer. Lets add some fun by changing the orientation of the splitter on a double click.

The event we need is DoubleClick. In case you've forgotten how to use dot net events from IronPython, we define a function or method which takes sender and event arguments. We then add in place (+=) it to the event on the control. The sender is the control that caused the event.

def SwapOrientation(sender, event):
    if sender.Orientation == Orientation.Vertical:
        sender.Orientation = Orientation.Horizontal
    else:
        sender.Orientation = Orientation.Vertical

splitter.DoubleClick += SwapOrientation

The Full Example

We're now ready to put together our full example application. We'll use different images for the second panel. The second image is of an IR Telescope. We'll also set multiple tab pages in both tab controls.

import clr
clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')

from System.Windows.Forms import (
    Application, DockStyle, Form, Orientation, PictureBox,
    PictureBoxSizeMode, SplitContainer,
    TabAlignment, TabControl, TabPage
)
from System.Drawing import Image

pathToFile1 = 'images/greenlake.jpg'
pathToFile2 = 'images/ir_telescope.jpg'

class MainForm(Form):

    def __init__(self):
        Form.__init__(self)

        self.setupImages()

        splitter = SplitContainer()
        splitter.Orientation = Orientation.Vertical
        splitter.Dock = DockStyle.Fill

        def SwapOrientation(sender, event):
            if sender.Orientation == Orientation.Vertical:
                sender.Orientation = Orientation.Horizontal
            else:
                sender.Orientation = Orientation.Vertical

        splitter.DoubleClick += SwapOrientation

        self.setupPanel(splitter.Panel1, self.image1)
        self.setupPanel(splitter.Panel2, self.image2)
        self.Controls.Add(splitter)

        self.Text = 'Our GUI Example'
        self.Show()


    def setupImages(self):
        self.image1 = Image.FromFile(pathToFile1)
        self.image2 = Image.FromFile(pathToFile2)

    def getPictureBox(self, image):
        pictureBox = PictureBox()
        pictureBox.SizeMode = PictureBoxSizeMode.StretchImage
        pictureBox.Image = image
        pictureBox.Dock = DockStyle.Fill
        return pictureBox

    def setupPanel(self, parent, image):
        tabControl = TabControl()
        tabControl.Dock = DockStyle.Fill
        tabControl.Alignment = TabAlignment.Bottom

        for i in range(5):
            tabPage = TabPage()
            tabPage.Text = 'Image %s' % i
            tabPage.Controls.Add(self.getPictureBox(image))

            tabControl.TabPages.Add(tabPage)

        parent.Controls.Add(tabControl)


Application.EnableVisualStyles()
form = MainForm()
Application.Run(form)

With a vertical splitter, this looks like :

A Vertical Splitter

After double clicking on the splitter it magically becomes :

A Horizontal Splitter

I hope you enjoyed it... Smile

For buying techie books, science fiction, computer hardware or the latest gadgets: visit The Voidspace Amazon Store.

Hosted by Webfaction

Return to Top

Page rendered with rest2web the Site Builder

Last edited Fri Nov 27 18:32:35 2009.

Counter...