본문 바로가기

TechLog

IronPython + WinForm = 크로스 플랫폼 GUI?

IronPython은 C#으로 작성된, Python의 .NET 구현이다. .NET 기반으로 구현되었기 때문에 (당연하지만) .NET 프레임워크에 직접 접근하여 필요한 기능을 가져다 쓸 수 있으며, 윈도우 기반 시스템에 잘 융합될 수 있다.

Python 언어에는 이미 다양한 GUI 툴킷(참고: http://wiki.python.org/moin/GuiProgramming)이 존재하고 있기 때문에 WinForm을 사용할 수 있다는 것이 IronPython의 별다른 장점이라기 보긴 어려울 것 같다. 아마 .NET에 익숙한 프로그래머가 다루기 쉽다는 정도로 생각하면 될 것이다.

IronPython의 코드를 살펴보기 전에, C#으로 작성된 전형적인 WinForm 프로그램의 코드를 한 번 살펴보자 (기본 윈폼 프로젝트를 생성하고 버튼을 하나 추가한 폼이다):

 

- Form1.Designer.cs

namespace WindowsFormsApplication1
{
    partial class Form1
    {
        /// <summary>
        /// 필수 디자이너 변수입니다.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 사용 중인 모든 리소스를 정리합니다.
        /// </summary>
        /// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form 디자이너에서 생성한 코드

        /// <summary>
        /// 디자이너 지원에 필요한 메서드입니다.
        /// 이 메서드의 내용을 코드 편집기로 수정하지 마십시오.
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(12, 12);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(75, 23);
            this.button1.TabIndex = 0;
            this.button1.Text = "button1";
            this.button1.UseVisualStyleBackColor = true;
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(292, 271);
            this.Controls.Add(this.button1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Button button1;
    }
}

 

- Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
        /// <summary>
        /// 해당 응용 프로그램의 주 진입점입니다.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

위 코드의 실행 결과는 다음과 같다:

 

 

 

위 코드를 IronPython으로 옮기면 어떻게 될까? (일단 아래 코드를 살펴보기 전에 http://ironpython.codeplex.com 사이트에서 IronPython 최신 버전을 다운받아 설치하도록 하자)

기본적으로 C# 프로그램에서는 Form의 코드와 Application 진입점에 해당하는 코드가 별도로 생성되지만, Python 코드는 인터프리터 언어다보니 굳이 그럴 필요는 없다:

 

- Program.py

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

from System.Windows.Forms import *
from System.Drawing import *
 
class MyForm(Form):
    def __init__(self):
        self.SuspendLayout()
        button = Button()
        button.Text = 'button1'
        button.Location = Point(12,12)
        button.Click += test
        self.Controls.Add(button)
        
        self.ResumeLayout(False)

def test(o, v):
    MessageBox.Show("Hello World")    

form = MyForm()
Application.Run(form)

 

그리고 위 코드를 실행하면 다음과 같은 결과를 볼 수 있다 (단순히 ipy.exe – IronPython Console을 실행해서 위 코드를 입력하면 된다):

 

버튼을 클릭하면 Hello World라는 문자열을 출력하는 메시지 박스가 나타나는 것도 볼 수 있다. 폼 이름의 설정 등 일부 코드가 생략되었지만, IronPython에는 이런 방식으로 WinForm 프로그래밍을 하는 것이 가능하다.

 

그런데 재미있는 것은, 이 IronPython 코드를 유닉스 기반 환경에서도 실행시켜 볼 수 있다는 것이다. .NET 프레임워크 환경은 윈도우 시스템에만 제공되는 것 아니냐고? 아니다. Mono라는 이름의 크로스 플랫폼/오픈 소스 프로젝트가 존재하고 있기 때문이다. 이 Mono를 사용하면 .NET 기반 코드를 유닉스 기반 시스템에서도 실행할 수 있게 되며, IronPython 또한(IronPython은 C#으로 구현되었다!) 유닉스 시스템에서 사용할 수 있다.

Mac OS X에 Mono와 IronPython을 설치하고 위 코드를 실행하면? 다음과 같이 실행되는 것을 볼 수 있다:

 

창의 헤더 부분은 조금 다르지만 내부 폼의 모양은 그대로이며, 버튼을 눌렀을 때 메시지 박스 출력도 올바로 작동한다.