wx,html 모듈을 이용하는 첫째 소스는 http 프로토콜만 지원하고 https 프로토콜은 지원하지 않습니다.

그러나,  wx,html2 모듈을 이용하는 둘째 소스는 http 프로토콜과 https 프로토콜 모두를 지원합니다.

셋째 소스는 둘째 소스에 네비게이터(뒤로 가기, 앞으로 가기) 가능을 추가한 소스입니다.

[1] wx.html 모듈을 이용한 소스: simple_html_browser.py

# -*- coding: utf-8 -*-
#!/usr/bin/env python

# Filename: simple_html_browser.py
# Execute: python simple_html_browser.py
#    or
# Execute: ./simple_html.browser.py

import wx
import wx.html

class MyHtmlDialog(wx.Dialog):
    def __init__(self, parent, title):
        wx.Dialog.__init__(self, parent, -1, title, size=(600,400))
        html = wx.html.HtmlWindow(self)
        if "gtk2" in wx.PlatformInfo:
            html.SetStandardFonts()

        wx.CallAfter(html.LoadPage, "http://www.google.com")

if __name__ == "__main__":
    app = wx.App()
    dlg = MyHtmlDialog(None, "Simple HTML Browser")
    dlg.ShowModal()
    dlg.Destroy()
    app.MainLoop()

 

[2] wx.html2 모듈을 이용한 소스: simple_html2_browser.py

# -*- coding: utf-8 -*-
#!/usr/bin/env python

# Filename: simple_html2_browser.py
# Execute: python simple_html2_browser.py
#    or
# Execute: ./simple_html2_browser.py

import wx
import wx.html2

class MyHtml2Dialog(wx.Dialog):
    def __init__(self, parent, title):
        wx.Dialog.__init__(self, parent, -1, title, size=(600,400))
        html = wx.html2.WebView.New(self)
        if "gtk2" in wx.PlatformInfo:
            html.SetStandardFonts()

        wx.CallAfter(html.LoadURL, "https://www.google.com")

if __name__ == "__main__":
    app = wx.App()
    dlg = MyHtml2Dialog(None, "Simple HTML2 Browser")
    dlg.ShowModal()
    dlg.Destroy()
    app.MainLoop()

 

 

[3] 위의 둘째 것을 쓸 만 한하게 수정한 웹 브라우저 소스: simple_browser_wk.py

# -*- coding: utf-8 -*-
#!/usr/bin/env python

# Filename: simple_browser_wk.py
#
# Execute: python3 simple_browser_wk.py
#    or
# Execute: pythonw simple_browser_wk.py
#    or
# Execute: ./simple_browser_wk.py
#
# Date: 2020.11.29   Version 0.0.4

import wx 
import wx.html2 

class MyBrowser(wx.Frame): 
    def __init__(self, parent, title): 
        super(MyBrowser, self).__init__(parent, title = title,size = (800,400))  
        sizer = wx.BoxSizer(wx.VERTICAL) 

        hsizer = wx.BoxSizer(wx.HORIZONTAL) 
        emptyText = wx.StaticText(self, -1 , "     ", (10, 10), (10, -1))
        emptyText.SetBackgroundColour('#DDDDDD')
        self.addrText = wx.TextCtrl(self, wx.ID_ANY, value="", size=(300, 30))
        self.addrText.SetFont( wx.Font(12, wx.ROMAN, wx.NORMAL, wx.NORMAL)  )
        self.addrText.SetBackgroundColour('white')
        self.addrText.Bind(wx.EVT_CHAR, self.OnCharEvent)
        self.prevButton = wx.Button(self, 1, '<', (10, 10), (20, -1))
        self.prevButton.Bind(wx.EVT_BUTTON, self.OnPrevButton, id=1)
        self.nextButton = wx.Button(self, 1, '>', (10, 10), (20, -1))
        self.nextButton.Bind(wx.EVT_BUTTON, self.OnNextButton, id=1)
        self.homeButton = wx.Button(self, 1, 'Home', (10, 10), (80, -1))
        self.homeButton.Bind(wx.EVT_BUTTON, self.OnHomeButton, id=1)
        self.exitButton = wx.Button(self, 1, 'Exit', (10, 10), (80, -1))
        self.exitButton.Bind(wx.EVT_BUTTON, self.OnCloseButton, id=1)

        hsizer.Add(self.exitButton, 3, wx.EXPAND, 10) 
        hsizer.Add(self.homeButton, 3, wx.EXPAND, 10) 
        hsizer.Add(self.prevButton, 1, wx.EXPAND, 10) 
        hsizer.Add(self.nextButton, 1, wx.EXPAND, 10) 
        hsizer.Add(self.addrText, 30, wx.EXPAND, 10) 
        hsizer.Add(emptyText, 1, wx.EXPAND, 10) 
        sizer.Add(hsizer, 1, wx.EXPAND, 10) 
        self.browser = wx.html2.WebView.New(self) 
        sizer.Add(self.browser, 20, wx.EXPAND, 10) 
        self.SetSizer(sizer) 
        self.SetSize((800, 700)) 
        self.Bind(wx.html2.EVT_WEBVIEW_NAVIGATED, self.OnNavigated)
        self.OpenWebPage("https://www.google.com")

    def OnCharEvent(self, event):
        keycode = event.GetKeyCode()
        controlDown = event.CmdDown()
        altDown = event.AltDown()
        shiftDown = event.ShiftDown()

        if (not shiftDown) and (not altDown) and (not controlDown) and keycode == 13 :      # [Enter] key
            self.OpenWebPage(self.addrText.GetValue())

    def OnCloseButton(self, event):
        self.Destroy()
        quit()

    def OnHomeButton(self, event):
        self.OpenWebPage("https://scripting.tistory.com")
        event.Skip()

    def OnPrevButton(self, event):
         if self.browser.CanGoBack():
             self.browser.GoBack()
         event.Skip()

    def OnNextButton(self, event):
         if self.browser.CanGoForward():
             self.browser.GoForward()
         event.Skip()

    def OnNavigated(self, event): 
        self.addrText.SetLabel(self.browser.CurrentURL)
        # print(self.browser.CurrentTitle)
        self.SetTitle("SimpleBrowser - {0}".format(self.browser.CurrentTitle))
        event.Skip()

    def OpenWebPage(self, addr): 
        self.browser.LoadURL(addr)
        self.SetTitle("Simpl Browser")
        self.addrText.SetLabel(addr)
        self.Show() 


if __name__ == "__main__":	
    ex = wx.App() 
    f = MyBrowser(None,'Simple Btowser') 
    f.Show()
    ex.MainLoop()
    

 

 

 

 

 

Posted by Scripter

댓글을 달아 주세요

최근(2020년 11월 21일)에 릴리즈 4.1.1이 발표되었습니다.

C++ 언어로 작성된 wxPython은 Python2 와 Python3  모두에 사용가능한

Python의 GUI 래퍼(wrapper)입니다.

 

[1] wxPython 홈페이지

[2] wxPython 4.1.1 설치하기

   처음 설치 명령: pippip install wxPython==4.1.1

   업그레이드 명령: pippip install --upgrade wxPython==4.1.1

 

[3] 설치 후 버전 확인하기

>>> import wx
>>> wx.version()
'4.1.1 msw (phoenix) wxWidgets 3.1.5'
>>> wx.__version__
'4.1.1'

[4] 설치된 wxPython의 버전을 확인하는 GUI 소스

# -*- coding: utf-8 -*-
#!/usr/bin/env python

# Filename: versionGUI.py
#
# Date: 2020.11.28

import wx


class VersionDialog(wx.Dialog):
    def __init__(self, parent, title):
        wx.Dialog.__init__(self, parent, -1, title, size=(475, 240))
        self.sbox = wx.StaticBox(self, -1, 'Version Information', (10, 20), size=(440, 100))        
        self.sbox.SetFont( wx.Font(10, wx.ROMAN, wx.NORMAL, wx.NORMAL)  )
        
        font = wx.Font(11, wx.ROMAN, wx.NORMAL, wx.NORMAL) 
        a = wx.StaticText(self, -1 , "wx.version() = {0}".format(wx.version()), (15, 60))
        a.SetFont( font )
        b = wx.StaticText(self, -1 , "wx.__version__ = %s" % wx.__version__, (15, 85))
        b.SetFont( font )
        
        wx.StaticLine(self, 1,  (15, 145), (430, 2))
        wx.Button(self, 1, 'Okay', (340, 165), (100, -1))
        self.Bind(wx.EVT_BUTTON, self.OnClose, id=1)

    def OnClose(self, event):
        self.Destroy()
        quit()


if __name__ == "__main__":
    app = wx.App()
    dia = VersionDialog(None, "Version of wxPython")
    dia.ShowModal()
    if dia != None:
        dia.Destroy()
    app.MainLoop()

실행 결과:

 

 

 

Posted by Scripter

댓글을 달아 주세요

다음은 Pythob 2.7.* 에 PyGTK 를 설치하여 실행되는 RPN 계산기 소스이다.

 

#!/usr/bin/env python

# Filename: rpnCalc.py
#           0,3
#
#   RPN Calculator using PyGTK
#   Modified from PyGTK/example/textview-basic.py

import pygtk
pygtk.require('2.0')
import gtk

class TextViewExample:
    def callback(self, widget, data=None):
        print "Hello again - %s was pressed" % data
        if data != None:
            self.textbuffer.insert(self.textbuffer.get_end_iter(), data + "\n")
               
    def enter_callback(self, widget, entry):
        entry_text = entry.get_text()
        print "Entry contents: %s\n" % entry_text
  
    def create_model(self):
        '''create the model - a ListStore'''
        self.store = gtk.ListStore(float)
        return self.store
 
    def create_columns(self, treeView):
        ''' create the columns '''
        rendererText = gtk.CellRendererText()
        rendererText.set_property('xalign', 1.0)   # work for right align
        column = gtk.TreeViewColumn(None, rendererText, text=0)
        column.set_sort_column_id(0)
        column.set_alignment(0.5)   # work for center align

        # append the column
        treeView.append_column(column)

    def reset(self, widget, entry):
        entry.set_text("")

    def calcIt(self, widget, entry):
        CONTINUE_FLAG = 1

        while CONTINUE_FLAG == 1:
            param = entry.get_text()
            tokens = self.tokenize(param)
            token_len = len(tokens)

            self.textbuffer.insert(self.textbuffer.get_end_iter(), "RPN> " + param + "\n")

            for i in range(0, token_len):
                    str = "" + tokens[i]
                    if len(str) == 0:
                        continue

                    a = str[0:1]

                    if a == 'Q' or a == 'q':
                        self.showMessage("Quit")
                        self.clear()
                        CONTINUE_FLAG = 0
                        break

                    if a in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.']:
                            self.push(eval(str))
                    elif a == '+':
                            if len(str) > 1:
                                self.push(eval(str))
                            else:
                                self.push(self.pop() + self.pop())
                    elif a == '-':
                            if len(str) > 1:
                                self.push(eval(str))
                            else:
                                op2 = self.pop();
                                self.push(self.pop() - op2)
                    elif a == '*':
                         if str == "**":
                                op2 = self.pop()
                                self.push(pow(self.pop(), op2))
                         else:
                                self.push(self.pop() * self.pop())
                    elif a == '/':
                            op2 = self.pop()
                            if op2 != 0.0:
                                self.push(self.pop() / op2)
                            else:
                                self.showMessage("zero divisor popped")
                    elif a == '^':
                            op2 = self.pop()
                            self.push(pow(self.pop(), op2))
                    elif a == '=' or a == 'p':
                            listmodel = self.listView.get_model()
                            y = listmodel.get_value(listmodel.get_iter_first(), 0)
                            self.showMessage("%s" % y)
                    elif a == 'c':
                            self.showMessage("Clear")
                            self.clear()
                    else:
                            self.showMessage("Unknown Command: " + a)
            CONTINUE_FLAG = 0
            entry.set_text("")


    # push f onto value stack
    def push(self, f):
        self.store.insert(0, [f])

    # pop top value from stack
    def pop(self):
        try:
             listmodel = self.listView.get_model()
             y = listmodel.get_value(listmodel.get_iter_first(), 0)
             self.store.remove(self.store.get_iter_first())
             return y
        except:
             raise "pop error on empty stack"
        return None

    # clear stack
    def clear(self):
        self.store.clear()


    # Tokenize the input string.
    def tokenize(self, s):
        self.len = len(s)
        t = ""
        tokens = []    # list of tokens

        for i in range(0, self.len):
            c = s[i:i+1]
            if c == ' ' or c == '\t' or c == '\r' or c == '\n':
                    if len(t) > 0:
                            tokens.append(t)
                            t = ""
            elif c == '+' or c == '-':
                    if len(t) > 0:
                            tokens.append(t)
                            t = c
                    elif len(t) == 0:
                            t = c
            elif c == '*':
                    if len(t) > 1:
                            tokens.append(t)
                            tokens.append(c)
                            t = ""
                    elif len(t) == 1:
                         if t == "*":
                                tokens.append("**")
                                t = ""
                         else:
                                tokens.append(t)
                                tokens.append(c)
                                t = ""
                    elif len(t) == 0:
                            t = c
            elif c == '/' or c == '^' or c == '=' or c == 'p' or c == 'q' or c == 'Q':
                    if len(t) > 0:
                            tokens.append(t)
                            tokens.append(c)
                            t = ""
                    elif len(t) == 0:
                            tokens.append(c)
            else:
                    t += c

        if len(t) > 0:
                tokens.append(t)
                t = ""
        return tokens


    def showMessage(self, m):
        if m != None:
            self.textbuffer.insert(self.textbuffer.get_end_iter(), "%s\n" % m)


    def close_application(self, widget):
        gtk.main_quit()

    def __init__(self):
        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        window.set_resizable(True) 
        window.connect("destroy", self.close_application)
        window.set_title("RPN Calculator")
        window.set_default_size(500, 300)
        window.set_border_width(0)

        box2 = gtk.VBox(False, 10)
        box2.set_border_width(10)
        window.add(box2)
        box2.show()

        hbox1 = gtk.HBox()
        box2.pack_start(hbox1, True, True, 0)
        hbox1.show()


        sw = gtk.ScrolledWindow()
        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        textview = gtk.TextView()
        self.textbuffer = textview.get_buffer()
        sw.add(textview)
        sw.show()
        textview.show()

        hbox1.pack_start(sw, True, True, 10)


        # create a scrollable window and integrate it into the vbox
        sw2 = gtk.ScrolledWindow()
        sw2.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        sw2.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
 
        # create a TreeView object which will work with our model (ListStore)
        store = self.create_model()
        self.listView = gtk.TreeView(store)
        self.listView.set_rules_hint(True)
        self.listView.set_headers_clickable(False)
        self.listView.set_property("headers-visible", False)
 
        # add the TreeView to the scrolled window
        sw2.add(self.listView)
 
        sw2.show()
        self.listView.show()

        # create the columns
        self.create_columns(self.listView)
        sw2.set_size_request(150, 300)
        hbox1.pack_start(sw2, False, False, 10)


        # check button to toggle editable mode
        textview.set_editable(False)
        textview.set_cursor_visible(False)
       
        hbox2 = gtk.HBox()
        box2.pack_start(hbox2, False, True, 0)
        hbox2.show()

        entry = gtk.Entry()
        entry.set_max_length(50)
        entry.connect("activate", self.enter_callback, entry)
        hbox2.pack_start(entry, True, True, 10)
        entry.show()

        hbox3 = gtk.HButtonBox()
        hbox2.pack_start(hbox3, False, False, 0)
        hbox3.show()

        btnCalc = gtk.Button("Calculate")
        btnCalc.connect("clicked", self.calcIt, entry)
        hbox3.pack_start(btnCalc, True, True, 5)
        btnCalc.set_flags(gtk.CAN_DEFAULT)
        btnCalc.grab_default()
        btnCalc.show()
       

        btnReset = gtk.Button("Reset")
        btnReset.connect("clicked", self.reset, entry)
        hbox3.pack_start(btnReset, True, True, 5)
        btnReset.set_flags(gtk.CAN_DEFAULT)
        btnReset.grab_default()
        btnReset.show()

        window.show()

def main():
    gtk.main()
    return 0      

if __name__ == "__main__":
    TextViewExample()
    main()

 

프롬프트> python rpnCalc.py

 

 

 

Posted by Scripter

댓글을 달아 주세요

현재 Python 3.3 의 최신 릴리즈는 3.3.5 이고, Python 3.4 의 최신 릴리즈는 3.3.1 이다. 또한 IPython 의 최신 릴리즈는 2.1.0 이다. 

 

여기서는 윈도우용 Python 3.3.5 를 설치한 후 IPython 2.1.0 을 설치하여 사용하는데 문제가 많아 그 한 해결법을 제시한다.'(윈도우용 Python 3.4.1 의 경우에는 IPython 2.1.0 이 무리 없이 잘 설치된다.)

 

이 글에서 IPython 을 포함하여 모든 Python 확장 모듈의 설치는 모두

Unofficial Windows Binaries for Python Extension Packages

의 것을 내려받아 설치하는 것으로 간주한다.

 

우선 Python 3.3.5 인터프리터를 실행해 본다. 

프롬프트> python
Python 3.3.5 (v3.3.5:62cf4e77f785, Mar  9 2014, 10:37:12) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> exit() 

이번에는 IPython 인터프리터를 실행해본다.  IPython 의 실행파일은 %PYTHONPATH%\Scripts 폴더에 존재하므로 이 폴더를 환경변수 PATH 에 넣어주어야 한다.

프롬프트> ipython
Traceback (most recent call last):
  File "c:\python335\Scripts\ipython-script.py", line 5, in <module>
    from pkg_resources import load_entry_point
ImportError: No module named 'pkg_resources'

 

위의 에러 메시지는 pkg_resources 모듈이 설치되어 있지 않다는 의미이다.

Python 3.4.1 을 설치하여 %PYTHONPATH%\Lib\site_packes 폴더에 있는 pkg_resource.py 파일을 Python 3.3.5 의 해당 폴더에 복사한 후 ipython 릏 다시 실행한다.

프롬프트> ipython
WARNING: Readline services not available or not loaded.
WARNING: Proper color support under MS Windows requires the pyreadline library.
You can find it at:
http://ipython.org/pyreadline.html
Gary's readline needs the ctypes module, from:
http://starship.python.net/crew/theller/ctypes
(Note that ctypes is already part of Python versions 2.5 and newer).

Defaulting color scheme to 'NoColor'
Python 3.3.5 (v3.3.5:62cf4e77f785, Mar  9 2014, 10:37:12) [MSC v.1600 32 bit (In
tel)]
Type "copyright", "credits" or "license" for more information.

IPython 2.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: exit()

 

이번에는 IPython 이 실행은 되었지만 색상이 지원되지않는다. 그래서 PyReadline 을 설치하고 다시 ipython 을 실행한다.


프롬프트> ipython
Python 3.3.5 (v3.3.5:62cf4e77f785, Mar  9 2014, 10:37:12) [MSC v.1600 32 bit (In
tel)]
Type "copyright", "credits" or "license" for more information.

IPython 2.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: exit()

위와 같이 IPython 2.1.0 이 잘 실행되었음을 알 수 있다.

 

64비트용 Python 3,3,5 의 경우에도 위와 같은 방법으러  IPython 2,1,9 을 설치하여 사용할 수 있다.

 

Python 3,4,1 의 경우 IPython 2.1.0 이 설치와 실행은 잘 되지만, 역시 색상은 지둰되지 않는다.

이 경우 PyReadline 을 설치하는 방법은

프롬프트> set PATH=%PYTHTHON341PATH%;%PYTHON341PATH%\Scripts;%PATH%

한 후 pip 명령으로 pyreadline 을 설치한다.

프롬프트> pip ionstall pyreadline

만일 pip 명렬으로 pyreadline 이 설치되지 않으면 Download PyReadline 에서 직법 내려받아 설치해도 된다. (32bit 용 Python 3.4.1 의 경우 이렇게 하여 성공적으로 설치하였다.)

 

참고로, Matplotlib 를 이용하기 위해서는 numpy, python-dateutil, pytz, pyparsing, six, pillow, pycairo, tornado, pyside, pyq 들이 먼저 설치되어 있어야 한다.

이제 Matplotlib 가 잘 설치되었는지 IPython 으로 테스트해 보자.

 

프롬프트> ipython -pylab

 WARNING: `-pylab` flag has been deprecated.
    Use `--matplotlib <backend>` and import pylab manually.
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:45:13) [MSC v.1600 64 bit (AM
D64)]
Type "copyright", "credits" or "license" for more information.

IPython 2.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.
Using matplotlib backend: TkAgg

In [1]: x = randn(10000)

In [2]: hist(x, 100)
Out[2]:
(array([   1.,    0.,    0.,    0.,    0.,    1.,    1.,    3.,    1.,
           2.,    3.,    2.,    2.,    5.,    6.,    4.,    5.,   10.,
           8.,   20.,   27.,   16.,   25.,   34.,   30.,   26.,   51.,
          60.,   70.,   66.,   86.,   97.,   88.,  108.,  118.,  140.,
         151.,  158.,  156.,  175.,  189.,  215.,  220.,  255.,  251.,
         273.,  267.,  260.,  295.,  285.,  314.,  320.,  298.,  285.,
         310.,  327.,  299.,  281.,  246.,  260.,  247.,  277.,  190.,
         199.,  186.,  187.,  206.,  139.,  135.,  131.,  126.,  100.,
         119.,   74.,   71.,   67.,   67.,   42.,   27.,   34.,   29.,
          30.,   24.,   15.,    8.,   13.,   12.,   11.,    3.,    7.,
           4.,    0.,    2.,    2.,    5.,    1.,    2.,    1.,    0.,    1.]),
 array([-3.96240846, -3.8868053 , -3.81120214, -3.73559898, -3.65999581,
        -3.58439265, -3.50878949, -3.43318633, -3.35758317, -3.28198001,
        -3.20637685, -3.13077368, -3.05517052, -2.97956736, -2.9039642 ,
        -2.82836104, -2.75275788, -2.67715471, -2.60155155, -2.52594839,
        -2.45034523, -2.37474207, -2.29913891, -2.22353574, -2.14793258,
        -2.07232942, -1.99672626, -1.9211231 , -1.84551994, -1.76991678,
        -1.69431361, -1.61871045, -1.54310729, -1.46750413, -1.39190097,
        -1.31629781, -1.24069464, -1.16509148, -1.08948832, -1.01388516,
        -0.938282  , -0.86267884, -0.78707567, -0.71147251, -0.63586935,
        -0.56026619, -0.48466303, -0.40905987, -0.3334567 , -0.25785354,
        -0.18225038, -0.10664722, -0.03104406,  0.0445591 ,  0.12016226,
         0.19576543,  0.27136859,  0.34697175,  0.42257491,  0.49817807,
         0.57378123,  0.6493844 ,  0.72498756,  0.80059072,  0.87619388,
         0.95179704,  1.0274002 ,  1.10300337,  1.17860653,  1.25420969,
         1.32981285,  1.40541601,  1.48101917,  1.55662233,  1.6322255 ,
         1.70782866,  1.78343182,  1.85903498,  1.93463814,  2.0102413 ,
         2.08584447,  2.16144763,  2.23705079,  2.31265395,  2.38825711,
         2.46386027,  2.53946344,  2.6150666 ,  2.69066976,  2.76627292,
         2.84187608,  2.91747924,  2.99308241,  3.06868557,  3.14428873,
         3.21989189,  3.29549505,  3.37109821,  3.44670137,  3.52230454,
         3.5979077 ]),
 <a list of 100 Patch objects>)

 

 

 

-pylab 옵션이 deprecate 되었다고 하니 이번에는 옵션--matplotlib 으로 실행해 보자.

프롬프트> ipython --matplotlib
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:45:13) [MSC v.1600 64 bit (AM
D64)]
Type "copyright", "credits" or "license" for more information.

IPython 2.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.
Using matplotlib backend: TkAgg

In [1]: from pylab import *

In [2]: x = randn(10000)

In [3]: hist(x, 100)
Out[3]:
(array([   2.,    1.,    1.,    1.,    1.,    3.,    7.,    5.,    1.,
           4.,   11.,   13.,   15.,   16.,   20.,   21.,   27.,   25.,
          31.,   34.,   47.,   47.,   62.,   70.,   68.,   79.,   98.,
         101.,  123.,  121.,  145.,  142.,  142.,  168.,  172.,  193.,
         212.,  235.,  229.,  227.,  240.,  236.,  296.,  286.,  259.,
         276.,  285.,  274.,  302.,  308.,  284.,  286.,  288.,  255.,
         251.,  234.,  215.,  198.,  216.,  183.,  192.,  175.,  175.,
         156.,  130.,  133.,  102.,  101.,   90.,   95.,   79.,   54.,
          63.,   57.,   50.,   32.,   36.,   33.,   24.,   21.,   23.,
          16.,    9.,    6.,   12.,    7.,    6.,    6.,    5.,    4.,
           1.,    4.,    2.,    2.,    2.,    1.,    3.,    0.,    0.,    1.]),
 array([-3.40718204, -3.33556225, -3.26394247, -3.19232268, -3.1207029 ,
        -3.04908311, -2.97746333, -2.90584354, -2.83422376, -2.76260398,
        -2.69098419, -2.61936441, -2.54774462, -2.47612484, -2.40450505,
        -2.33288527, -2.26126548, -2.1896457 , -2.11802592, -2.04640613,
        -1.97478635, -1.90316656, -1.83154678, -1.75992699, -1.68830721,
        -1.61668742, -1.54506764, -1.47344785, -1.40182807, -1.33020829,
        -1.2585885 , -1.18696872, -1.11534893, -1.04372915, -0.97210936,
        -0.90048958, -0.82886979, -0.75725001, -0.68563023, -0.61401044,
        -0.54239066, -0.47077087, -0.39915109, -0.3275313 , -0.25591152,
        -0.18429173, -0.11267195, -0.04105216,  0.03056762,  0.1021874 ,
         0.17380719,  0.24542697,  0.31704676,  0.38866654,  0.46028633,
         0.53190611,  0.6035259 ,  0.67514568,  0.74676546,  0.81838525,
         0.89000503,  0.96162482,  1.0332446 ,  1.10486439,  1.17648417,
         1.24810396,  1.31972374,  1.39134353,  1.46296331,  1.53458309,
         1.60620288,  1.67782266,  1.74944245,  1.82106223,  1.89268202,
         1.9643018 ,  2.03592159,  2.10754137,  2.17916115,  2.25078094,
         2.32240072,  2.39402051,  2.46564029,  2.53726008,  2.60887986,
         2.68049965,  2.75211943,  2.82373921,  2.895359  ,  2.96697878,
         3.03859857,  3.11021835,  3.18183814,  3.25345792,  3.32507771,
         3.39669749,  3.46831728,  3.53993706,  3.61155684,  3.68317663,
         3.75479641]),
 <a list of 100 Patch objects>)

 

 

 

이제 32비트용 Python 3.4.1 에서 Matplotlib 를 사용해 보자.

32비트용 Python 3.4.1 이 폴더 C:\Python34-32 에 설치된 것으로 간주한다.

먼저 명령 프롬프트에서 환경변수 PATH 를 설정한다.

프롬프트> pythonset PATH=C:\Python34-32;C:\Python34-32\Scripts;%PATH%

Pyhon 인터프리터를 실행하여 간단한 코드

import matplotlib.pyplot as plt
plt.plot([1,2,3,4])
plt.ylabel('some numbers')
plt.show()

를 입력한다.

프롬프트> python
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:38:22) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import matplotlib.pyplot as plt
Traceback (most recent call last):
  File "c:\python34-32\lib\site-packages\matplotlib\__init__.py", line 111, in <
module>
    import dateutil
ImportError: No module named 'dateutil'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\python34-32\lib\site-packages\matplotlib\__init__.py", line 113, in <
module>
    raise ImportError("matplotlib requires dateutil")
ImportError: matplotlib requires dateutil
>>> plt.plot([1,2,3,4])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'plt' is not defined
>>> plt.ylabel('some numbers')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'plt' is not defined
>>> plt.show()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'plt' is not defined
>>> exit()


위의 에러 메시징[서 보다 시피, 모듈 dateutil 이 없다는 에러다.

이번에는 IPython 을 실행해 본다.

프롬프트> ipython
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:38:22) [MSC v.1600 32 bit (In
tel)]
Type "copyright", "credits" or "license" for more information.

IPython 2.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: exit()

IPython 은 정상적으로 잘 실행된다.

pip 명령으로 python-dateutil 을 설치한다.

프롬프트> pip install python-dateutil
Downloading/unpacking python-dateutil
  Running setup.py (path:C:\Users\ph\AppData\Local\Temp\pip_build_ph\python-date
util\setup.py) egg_info for package python-dateutil

Requirement already satisfied (use --upgrade to upgrade): six in c:\python34-32\
lib\site-packages (from python-dateutil)
Installing collected packages: python-dateutil
  Running setup.py install for python-dateutil

Successfully installed python-dateutil
Cleaning up...

 

다시 Pyhon 인터프리터를 실행하여 앞에서 제시했던 간단한 코드를 입력해 본다.

프롬프트> python
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:38:22) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import matplotlib.pyplot as plt
Traceback (most recent call last):
  File "c:\python34-32\lib\site-packages\matplotlib\__init__.py", line 125, in <
module>
    import pyparsing
ImportError: No module named 'pyparsing'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\python34-32\lib\site-packages\matplotlib\__init__.py", line 127, in <
module>
    raise ImportError("matplotlib requires pyparsing")
ImportError: matplotlib requires pyparsing
>>> plt.plot([1,2,3,4])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'plt' is not defined
>>> plt.ylabel('some numbers')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'plt' is not defined
>>> plt.show()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'plt' is not defined
>>> exit()

 

위의 에러 메시징[서 보다 시피, 이번에는 모듈 pyparsing 이 없다는 에러다.

그래서 pip 명령으로 pyparsing 을 설치한다.

프롬프트> pip install pyparsing
Downloading/unpacking pyparsing
  Running setup.py (path:C:\Users\ph\AppData\Local\Temp\pip_build_ph\pyparsing\s
etup.py) egg_info for package pyparsing

Installing collected packages: pyparsing
  Running setup.py install for pyparsing

Successfully installed pyparsing
Cleaning up...

 

python-dateutil 과 ptparsing 이 설치되었으니 다시 Pyhon 인터프리터를 실행하여 앞에서 제시했던 간단한 코드를 입력해 본다.

프롬프트> python
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:38:22) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import matplotlib.pyplot as plt
>>> plt.plot([1,2,3,4])
[<matplotlib.lines.Line2D object at 0x045BE530>]
>>> plt.ylabel('some numbers')
<matplotlib.text.Text object at 0x047160B0>
>>> plt.show()

위의 명령이 모두 수행되어 아래 처럼 Matplotlib 에 의한 그래프 창이 성공적으로 뜬다.

 


 

이번에는 좌표평면의 네 점 (1, 1), (2, 4), (3, 9), (4, 16) 에 (속이 채워진) 뿕은 색의 굵은 점을 찍어본다.

>>> import matplotlib.pyplot as plt
>>> plt.plot([1,2,3,4], [1,4,9,16], 'ro')
[<matplotlib.lines.Line2D object at 0x042EE3B0>]
>>> plt.axis([0, 6, 0, 20])
[0, 6, 0, 20]
>>> plt.show()

 

 

 

이번에는 NumPy 모듈을 이용하여, 한 좌표평면의 세 함수 y = x, y = x^2, y = x^3 의 그래프를 그려 보자.

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> t = np.arange(0., 5., 0.2)
>>> plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^')
[<matplotlib.lines.Line2D object at 0x04716410>, <matplotlib.lines.Line2D object
 at 0x047169F0>, <matplotlib.lines.Line2D object at 0x047160F0>]
>>> plt.show()

 

 

 

* 이 외에도 Matplotlib 튜토리얼의 다른 예제 들도 잘 실행됨을 확인하였다.

 

 

Posted by Scripter

댓글을 달아 주세요

Pytghon 스크립트로 버전을 알아내는 방법 중에 하나는

import sys

sys.version_info

를 이용하는 것이다.

 

* Pyhoin 3.3 의 경우

Python 3.3.3 (v3.3.3:c3896275c0f6, Nov 18 2013, 21:19:30) [MSC v.1600 64 bit (AM
D64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.version_info
sys.version_info(major=3, minor=3, micro=3, releaselevel='final', serial=0)
>>> sys.version_info > (2, 4)
True
>>> sys.version_info >= (2, 4)
True
>>> sys.version_info >= (3, 0)
True

>>> type(sys.version_info)
<class 'sys.version_info'>

 

 

* Python 2.7 의 경우

Python 2.7.5 (default, Oct  2 2013, 22:34:09)
[GCC 4.8.1] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.version_info
sys.version_info(major=2, minor=7, micro=5, releaselevel='final', serial=0)
>>> sys.version_info > (2, 4)
True
>>> sys.version_info > (2, 7)
True
>>> sys.version_info >= (2, 7)
True
>>> sys.version_info >= (2, 8)
False

>>> sys.version_info >= (3, 0)
False

>>> type(sys.version_info)
<type 'sys.version_info'>

 

 

 

Posted by Scripter

댓글을 달아 주세요

* pyqtgraph 내려받기

 

* 예제 소스 (극곡선 r = 2 cos(3 theta) 그리기)

# -*- coding: utf-8 -*-

# Filename: testPyQtGraph_03.py
# Execute: python testPyQtGraph_03.py


from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg

app = QtGui.QApplication([])

win = pg.GraphicsWindow(title="Basic plotting examples")

win.resize(400, 500)
win.setWindowTitle('pyqtgraph example: Plotting')

# Enable antialiasing for prettier plots
pg.setConfigOptions(antialias=True)

p1 = win.addPlot(title="Parametric, grid enabled")
a = 2.0
k = 3.0
theta = np.linspace(0, 2*np.pi, 1000)
x = a*np.cos(theta)*np.cos(k*theta)
y = a*np.sin(theta)*np.cos(k*theta)
p1.plot(x, y)
p1.showGrid(x=True, y=True)

if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

 

* 실행 결과:

 

 

더 많은 pyqtgraph 예제:

프롬프트> cd %PYTHON27_HOME%\\Lib\site-packages\pyqtgraph

프롬프트> python -m examples

 

 

 

Posted by Scripter

댓글을 달아 주세요

** PySide 설치하기

** QtDesigner 내려받기

** 윈도우즈 용 git 를 설치하기

 

* 다음 소스는 http://qt-project.org/wiki/PySideSimplicissimus_Module_2_CloseButton 에서 볼 수 있는 소스이다.

 

#!/usr/bin/env python

# quitter.py - provide a button to quit this "program"

import sys

from PySide.QtGui import QMainWindow, QPushButton, QApplication
from ui_quitter import Ui_MainWindow

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    frame = MainWindow()
    frame.show()   
    app.exec_()

 

프롬프트> python quitter.py
Traceback (most recent call last):
  File "quitter.py", line 8, in <module>
    from ui_quitter import Ui_MainWindow
ImportError: No module named ui_quitter

ui_quitter 모듈이 없다는 에러 메시지이다.

 

* quitter.ui 를 구하기 위한  tuts4pyside 를 내려 받기 (quiter.ui 파일은 QtDesigner 를 이용하여 만든 파일이다.)

프롬프트> git clone https://github.com/OldAl/tuts4pyside

 

* quitter.ui 복사하기 (quittere,ui 파일을 현재 폴더에 복사한다.)

프롬프트> copy .\tuts4pyside\quit_prog\quitter.ui

* quitter.ui 로 부터 ui_quitter.py 를 생성하기 (실행 파일 pyside_uic.exe 는 C:\Python27\Scripts 폴더에 존재한다.)

프롬프트> c:\python27\scripts\pyside-uic quitter.ui -o ui_quitter.py

 

* 실행하기

프롬프트> python quitter.py

 

 

 

 

Posted by Scripter

댓글을 달아 주세요

전개 공식

        (ax + b)(cx + d) = acx^2 + (ad + bc)x + bd

에 기반을 둔 쉬운 곱셉법(일명 카라슈바 곱셈법)이다.

여기서 특히 a == b or a == c or b == d or c == d 인 경우이면

      ad + bc = s(c + d)  or ad + bc = a(b + d)

      or ad + bc = b(s + c) or ad + bc = c(a + b)

로 더 쉬운 곱셈 계산이 가능하다.

 

#!/usr/bin/python
# -*- coding: utf-8 -*-


# Filename: ezMult_02.py
#
# Execute: python ezMult_02.py
#
# See: http://zetcode.com/gui/pyqt4/widgets2/
# See: http://zetcode.com/gui/pyqt4/


import sys
import sys, random
from PyQt4 import QtGui, QtCore

class Example(QtGui.QWidget):
   
    def __init__(self):
        super(Example, self).__init__()
       
        self.ngame = 1
        self.npoint = 0
        self.doneflag = False
       
        self.initUI()
       
    def initUI(self):
        self.rect = QtCore.QRect(0, 30, 300, 220)
        self.xa = random.randint(11, 99)
        self.ya = random.randint(11, 99)
        self.lblXA = QtGui.QLabel(self)
        self.lblYA = QtGui.QLabel(self)
        self.lblYA.setFont(QtGui.QFont('Decorative', 16))
        self.lblXA.setFont(QtGui.QFont('Decorative', 16))
        self.lblXA.setText(str(self.xa))
        self.lblYA.setText(str(self.ya))
        self.lblXA.move(80, 60)
        self.lblYA.move(80, 80)

        self.lblAA = QtGui.QLabel(self)
        self.lblAA.setFont(QtGui.QFont('Decorative', 16))
        self.lblAA.setText("")
        self.lblAA.move(65, 90)

        self.lblBA = QtGui.QLabel(self)
        self.lblBA.setFont(QtGui.QFont('Decorative', 16))
        self.lblBA.setText("")
        self.lblBA.move(105, 110)

        self.lblCA = QtGui.QLabel(self)
        self.lblCA.setFont(QtGui.QFont('Decorative', 16))
        self.lblCA.setText("")
        self.lblCA.move(105, 120)

        self.lblOpa = QtGui.QLabel(self)
        self.lblOpa.setFont(QtGui.QFont('Decorative', 16))
        self.lblOpa.setText("X")
        self.lblOpa.move(40, 80)


        self.x = random.randint(11, 99)
        self.y = random.randint(11, 99)
        self.lblX = QtGui.QLabel(self)
        self.lblY = QtGui.QLabel(self)
        self.lblX.setText(str(self.x))
        self.lblY.setText(str(self.y))
        self.lblX.move(160, 40)
        self.lblY.move(160, 60)
        self.lblOp = QtGui.QLabel(self)
        self.lblOp.setText("X")
        self.lblOp.move(120, 60)
       
       
        self.lbl = QtGui.QLabel(self)
        self.lbl.move(60, 40)
        self.lbl.setHidden(True)

        self.lblScore = QtGui.QLabel(self)
        self.lblScore.setText("Score:")
        self.lblScore.move(10, 10)

        self.lblMsg = QtGui.QLabel(self)
        self.lblMsg.setText("Your first game")
        self.lblMsg.move(10, 255)

        self.lblScore.setFont(QtGui.QFont('Times New Roman', 12))
        self.lblMsg.setFont(QtGui.QFont('Times New Roman', 12))
       
       
        self.qleA = QtGui.QLineEdit(self)
        self.qleA.setFont(QtGui.QFont('Decorative', 20))
        self.qleA.setMaxLength(4)

        self.qleA.move(165, 90)
        self.qleA.resize(80, 30)

        self.qleB = QtGui.QLineEdit(self)
        self.qleB.setFont(QtGui.QFont('Decorative', 20))
        self.qleB.setMaxLength(3)
       
        self.qleB.move(165, 125)
        self.qleB.resize(60, 30)

        self.qleC = QtGui.QLineEdit(self)
        self.qleC.setFont(QtGui.QFont('Decorative', 20))
        self.qleC.setMaxLength(4)
       
        self.qleC.move(165, 170)
        self.qleC.resize(80, 30)

        if self.isSimple(self.xa, self.ya):
            self.redrawSimpleSubTable()
        else:
            self.redrawSubTable()
           
        if self.isSimple(self.x, self.y):
            self.redrawSimpleTable()
        else:
            self.redrawTable()
           
        self.btnExit = QtGui.QPushButton('Exit', self)
        self.btnExit.move(310, 60)
        self.btnExit.clicked.connect(self.doExit)
        self.btnExit.setEnabled(False)    

        self.btnMore = QtGui.QPushButton('More', self)
        self.btnMore.move(310, 120)
        self.btnMore.clicked.connect(self.moreGame)
        self.btnMore.setEnabled(False)  

        self.btnConfirm = QtGui.QPushButton('Ok', self)
        self.btnConfirm.move(310, 180)
        self.btnConfirm.clicked.connect(self.scoreGame)

        self.btnExit.setFont(QtGui.QFont('Arial', 12))
        self.btnMore.setFont(QtGui.QFont('Arial', 12))
        self.btnConfirm.setFont(QtGui.QFont('Arial', 12))


        self.qleA.textChanged[str].connect(self.onChanged)
       
        self.setGeometry(300, 300, 420, 280)
        self.setWindowTitle('Training Tool for Easy Multiplication')
        self.show()


    def moreGame(self):  
        self.update(self.rect)
          
        self.xa = random.randint(11, 99)
        self.ya = random.randint(11, 99)
        self.lblXA.setText(str(self.xa))
        self.lblYA.setText(str(self.ya))
       
        self.x = random.randint(11, 99)
        self.y = random.randint(11, 99)
        self.lblX.setText(str(self.x))
        self.lblY.setText(str(self.y))
       
        self.qleA.setText("")
        self.qleB.setText("")
        self.qleC.setText("")
       
        if self.isSimple(self.xa, self.ya):
            self.redrawSimpleSubTable()
        else:
            self.redrawSubTable()
           
        if self.isSimple(self.x, self.y):
            self.redrawSimpleTable()
        else:
            self.redrawTable()

        self.show()
        self.qleA.setFocus(True)    # See: http://pyqt.sourceforge.net/Docs/PyQt4/qwidget.html
        self.btnMore.setEnabled(False)  
        self.btnConfirm.setEnabled(True) 

        if self.ngame == 1:
            self.lblMsg.setText("Your first game")
        elif self.ngame == 2:
            self.lblMsg.setText("Your second game")
        elif self.ngame == 3:
            self.lblMsg.setText("Your third game")
        elif self.ngame == 4:
            self.lblMsg.setText("Your fourth game")
        elif self.ngame == 5:
            self.lblMsg.setText("Your fFifh game")
        else:
            self.lblMsg.setText("Your %d-th game" % self.ngame)
        self.lblMsg.adjustSize()


    def scoreGame(self):
        c = int(self.qleC.text())
       
        if self.isSimple(self.x, self.y):
            if c == self.x*self.y:
                 self.npoint += 1
                 self.lblMsg.setText("Right!")
                 if self.npoint == 5 and self.npoint == self.ngame:
                     self.lblMsg.setText("Congratulation!!")
                 self.lblMsg.adjustSize()
            else:
                s3 = "%d -> %d" % (c,  self.x*self.y)
                self.lblMsg.setText("Wrong! (%s)" % s3)
                self.lblMsg.adjustSize()
        else:
            a = int(self.qleA.text())
            b = int(self.qleB.text())
            if a == int(self.x / 10)*int(self.y / 10)*100 + (self.x % 10)*(self.y % 10) and \
                         b == int(self.x / 10)*(self.y % 10) + (self.x % 10)*int(self.y / 10) and \
                         c == self.x*self.y:
                 self.npoint += 1
                 self.lblMsg.setText("Right!")
                 if self.npoint == 5 and self.npoint == self.ngame:
                     self.lblMsg.setText("Congratulation!!")
                 self.lblMsg.adjustSize()
            else:
                s1 = ""
                if a != int(self.x / 10)*int(self.y / 10)*100 + (self.x % 10)*(self.y % 10):
                    s1 = "%d -> %d" % (a,  int(self.x / 10)*int(self.y / 10)*100 + (self.x % 10)*(self.y % 10))
                s2 = ""
                if b !=int(self.x / 10)*(self.y % 10) + (self.x % 10)*int(self.y / 10):
                    if len(s1) > 0:
                        s2 = ", "
                    s2 += "%d -> %d" % (b, int(self.x / 10)*(self.y % 10) + (self.x % 10)*int(self.y / 10))
                s3 = ""
                if c != self.x*self.y:
                    if len(s2) > 0:
                        s3 = ", "
                    s3 += "%d -> %d" % (c,  self.x*self.y)
                self.lblMsg.setText("Wrong! (%s%s%s)" % (s1, s2, s3))
                self.lblMsg.adjustSize()
       
        self.lblScore.setText("Your current score is %d in %d tries," % (20*self.npoint, self.ngame))
        self.lblScore.adjustSize()

        self.ngame += 1

        if self.ngame <= 5:
            self.btnMore.setEnabled(True)   
            self.btnMore.setFocus(True)    
        else:
            self.btnExit.setEnabled(True)  
            self.btnExit.setFocus(True)  
            self.btnMore.setEnabled(False)    
        self.btnConfirm.setEnabled(False)   


    def isSimple(self, x, y):
        if int(x/10) == int(y/10) or x % 10 == y % 10    \
                    or int(x/10) == x % 10 or int(y/10) == y % 10:
            return True
        else:
            return False


    def redrawSimpleSubTable(self):
        self.lblAA.setHidden(True)
        self.lblBA.setHidden(True)
        ca = int(self.xa) * int(self.ya)
        if len(str(ca)) == 3:
            self.lblCA.setText(str(ca))
            self.lblCA.move(72, 109)
            self.lblCA.adjustSize()
        else:
            self.lblCA.setText(str(ca))
            self.lblCA.move(60, 109)
            self.lblCA.adjustSize()


    def redrawSimpleTable(self):
        self.qleA.setHidden(True)
        self.qleB.setHidden(True)
        c = int(self.x) * int(self.y)
        if len(str(c)) == 3:
            self.qleC.setMaxLength(3)
            self.qleC.move(213, 110)
            self.qleC.resize(60, 30)
        else:
            self.qleC.setMaxLength(4)
            self.qleC.move(195, 110)
            self.qleC.resize(80, 30)


    def redrawSubTable(self):
        self.lblAA.setHidden(False)
        self.lblBA.setHidden(False)
        aa = int(self.xa/10) * int(self.ya / 10) * 100 + (self.xa % 10) * (self.ya % 10)
        if len(str(aa)) == 3:
            self.lblAA.setText(str(aa))
            self.lblAA.move(72, 109)
            self.lblAA.adjustSize()
        else:
            self.lblAA.setText(str(aa))
            self.lblAA.move(60, 109)
            self.lblAA.adjustSize()

        ba = int(self.xa % 10) * int(self.ya / 10) +  int(self.xa / 10) * int(self.ya %10)
        if len(str(ba)) == 1:
             self.lblBA.setText(str(ba))
             self.lblBA.move(84, 133)
             self.lblBA.adjustSize()
        elif len(str(ba)) == 2:
             self.lblBA.setText(str(ba))
             self.lblBA.move(72, 133)
             self.lblBA.adjustSize()
        else:
             self.lblBA.setText(str(ba))
             self.lblBA.move(60, 133)
             self.lblBA.adjustSize()

        ca = int(self.xa) * int(self.ya)
        if len(str(ca)) == 3:
             self.lblCA.setText(str(ca))
             self.lblCA.move(72, 164)
             self.lblCA.adjustSize()
        else:
             self.lblCA.setText(str(ca))
             self.lblCA.move(60, 164)
             self.lblCA.adjustSize()


    def redrawTable(self):
        self.qleA.setHidden(False)
        self.qleB.setHidden(False)
        a = int(self.x/10) * int(self.y / 10)
        if len(str(a)) == 1:
            self.qleA.setMaxLength(3)
            self.qleA.move(213, 110)
            self.qleA.resize(60, 30)
        else:
            self.qleA.setMaxLength(4)
            self.qleA.move(195, 110)
            self.qleA.resize(80, 30)

        b = int(self.x % 10) * int(self.y / 10) +  int(self.x / 10) * int(self.y %10)
        if len(str(b)) == 1:
             self.qleB.setMaxLength(1)
             self.qleB.move(235, 145)
             self.qleB.resize(20, 30)
        elif len(str(b)) == 2:
             self.qleB.setMaxLength(2)
             self.qleB.move(213, 145)
             self.qleB.resize(40, 30)
        else:
             self.qleB.setMaxLength(3)
             self.qleB.move(195, 145)
             self.qleB.resize(60, 30)

        c = int(self.x) * int(self.y)
        if len(str(c)) == 3:
            self.qleC.setMaxLength(3)
            self.qleC.move(213, 190)
            self.qleC.resize(60, 30)
        else:
            self.qleC.setMaxLength(4)
            self.qleC.move(195, 190)
            self.qleC.resize(80, 30)


    def paintEvent(self, e):
        qp = QtGui.QPainter()
        qp.begin(self)
        self.drawLines(qp)
        qp.end()
       
    def drawLines(self, qp):
        penA = QtGui.QPen(QtCore.Qt.black, 1, QtCore.Qt.SolidLine)
        qp.setPen(penA)
        if self.isSimple(self.xa, self.ya):
            qp.drawLine(37, 103, 107, 103)
        else:
            qp.drawLine(37, 103, 107, 103)
            qp.drawLine(37, 156, 107, 156)
       
        pen = QtGui.QPen(QtCore.Qt.black, 2, QtCore.Qt.SolidLine)
        qp.setPen(pen)
        if int(self.x/10) == int(self.y/10) or self.x % 10 == self.y % 10    \
                    or int(self.x/10) == self.x % 10 or int(self.y/10) == self.y % 10:
            qp.drawLine(170, 100, 270, 100)
        else:
            qp.drawLine(170, 100, 270, 100)
            qp.drawLine(170, 185, 270, 185)

        qp.setFont(QtGui.QFont('Decorative', 20))
        self.lblX.setFont(QtGui.QFont('Decorative', 20))
        self.lblY.setFont(QtGui.QFont('Decorative', 20))
        self.lblX.setText(str(self.x))
        self.lblY.setText(str(self.y))
        self.lblX.move(230, 40)
        self.lblX.adjustSize()
        self.lblY.move(230, 70)
        self.lblY.adjustSize()
        self.lblOp.setFont(QtGui.QFont('Decorative', 20))
        self.lblOp.move(170, 70)
        self.lblOp.adjustSize()

 

    def onChanged(self, text):

        self.lbl.setText(text)
        self.lbl.adjustSize()       
       
    def doExit(self):
        sys.exit(0)


def main():
        app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

 

실행 중인 창:

 

 

 

Posted by Scripter

댓글을 달아 주세요

* PyQt 내려받기: http://www.riverbankcomputing.co.uk/software/pyqt/download

 (Qt Designer 의실행 파일은 %Python27_HOME%\Lib\site-packages\PyQt4\Designer.exe 이다.)

Qt Designer 는 Visual Studio 의 Visual Basic 개발 환경과 비슷한 Python GUI 개발 도구이다.

다음은 책  Hello World! Second Edition: Computer Programming for Kids and Other Beginners 의 제 20 장에 소개되어 있는 예제를 한국어로 번안한 것이다.

 

Qt Designer 를 실행하여 다음과 같이 "새 폼" 창에서 "Main Window" 를 선택하고 "생성" 버튼을 클릭한다.

 

 

 위젯

  텍스트

 objectName

 Push Button

 Celsius to Fahrenheit >>>

 btn_CtoF

 Push Button

 <<< Fahrenheit to Celsius

 btn_FtoC

 Label

 Celsius

 

 Label

 Fahrenheit

 

 Line Edit

 

 editCel

 Spin Box

 

 spinFahr

* 주의: 폰트 설정 시 한글명 폰트(예: 바탕)를 선택하면 에러가 난다. 

 

위와 같이 디자인된 폼을 파일명 tempconv.ui 으로 저장한다.

 

소스 파일 tempconv.py 의 내용

# -*- encoding: utf-8 -*-

# PyQt 를 이용하는 온도 변환 프로그램

import sys
from PyQt4 import QtCore, QtGui, uic

form_class = uic.loadUiType("tempconv.ui")[0]                 # UI 탑재

class MyWindowClass(QtGui.QMainWindow, form_class):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.btn_CtoF.clicked.connect(self.btn_CtoF_clicked)  # 버튼에 이벤트 핸들러를
        self.btn_FtoC.clicked.connect(self.btn_FtoC_clicked)  #   묶는다.

    def btn_CtoF_clicked(self):                # CtoF 버튼의 이벤트 핸들러
        cel = float(self.editCel.text())         #
        fahr = cel * 9 / 5.0 + 32                 #
        self.spinFahr.setValue(int(fahr + 0.5))  #

    def btn_FtoC_clicked(self):                  # FtoC 버튼의 이벤트 핸들러
        fahr = self.spinFahr.value()             #
        cel = (fahr - 32) / 9.0 * 5
        self.editCel.setText(str(cel))           #

app = QtGui.QApplication(sys.argv)
myWindow = MyWindowClass(None)
myWindow.show()
app.exec_()

 

버튼에 이벤트 핸들러를 묶어 주는 구문은

                  버튼명.clicked.connect(메소드명) 

이다.

 

실행하기:

프롬프트> python convtemp.py

 

 

Posted by Scripter

댓글을 달아 주세요

EditPlus3 의 메뉴에서

   도구(T) -----> 기본 설정(P) ...

을 택하고 기본 설정 창에서 아래와 같이 "사용자 도구" 항목을 지정한다.

 

 

 Python3 용 소스 파일 helloPython3.py 를 아래 처럼 작성하고 저장한 후 Ctrl+1 (숫지 1) 키를 누른다. (파일 저장시에는 BOM 없는 UTF-8 인코딩으로 지정한다.)

 

 

Posted by Scripter

댓글을 달아 주세요