GUI programming in Python

Common GUI tools

  • Tkinter:Python's standard GUI Library
  • wxPython: it is more powerful than Tkiner and can cross platform
  • Pyqt
  • PyObject et al

Wxpyron installation

pip install wxPython

Three steps to establish python GUI program

1. Import wxPython packages or other packages

2. Establish framework

3. Establish main program

  • The frame cannot be seen until FrameShow(Ture) is executed
  • Execute app The framework cannot process events until mainloop()

4,Frame

  • Frame: frame (form), container, movable and zoomable, including title bar, menu, etc. the parent class of all frames. When using, you need to derive subclasses, and the constructor format of its base class is:
    wx.Frame.init (parent, id, title, pos, size, style, name )
  • Parent: the parent form of the frame.
  • ID: the wxpthon ID number of the new form. You can explicitly pass one or - 1, and wxpthon will automatically generate a new ID.
  • Title: the title of the form
  • pos: wx.Point object that specifies the position of the upper left corner of the new form on the screen. Usually (0,0) is the upper left corner of the display. When it is set to wx.DefaultPosition, its value is (- 1, - 1), which means that the system determines the position of the form.
  • Size: a Wx Size object, which specifies the initial size of the new form. When set to Wx When defaultsize, its value is (- 1, - 1), which means that the initial size of the form is determined by the system.
  • style: Specifies the type of form.
  • Name: the name of the framework.
  • When all parameters in front of a parameter are set, the parameter can omit its name and fill in its value directly. Otherwise, the format of "parameter name = value" needs to be used.

wx. Common styles of frame:

wx.CAPTION: Add title block
wx.DEFAULT_FRAME_STYLE: Default style
wx.CLOSE_BOX: Show close button on title bar
wx.MAXIMIZE_BOX: Show maximize button on title bar
wx.MINIMIZE_BOX: Show minimize button on title bar
wx.RESIZE_BORDER: Borders can be resized
wx.SIMPLE_BORDER: The border is not decorated
wx.SYSTEM_MENU: Add system menu (with "close", "move", "change size" and other functions)
wx.FRAME_SHAPED:Frames created with this style can use SetShape()Method to create a non rectangular form
wx.FRAME_TOOL_WINDOW: Give the frame a title bar smaller than normal to make the frame look like a tool box form

TextCtrl style

wx.TE_CENTER: The text in the control is centered.
wx.TE_LEFT: Aligns the text in the control to the left. Default behavior.
wx.TE_NOHIDESEL: Text is always highlighted for Windows. 
wx.TE_PASSWORD: The text you type is not displayed, instead it is displayed with an asterisk.
wx.TE_READONLY: The text control is read-only and the user cannot modify the text in it.
wx.TE_RIGHT: Right aligns the text in the control.
wx.TE_MULTILINE: Multiline text control
 Important methods:
use GetValue()Method to obtain the content entered in the text box, using SetValue()Method to set the text in the text box

Experimental content

Experiment 1

Write code by selecting the radio button, Write the corresponding information into the first TextCtrl (on the right side of FrameMouse). If FrameSize is selected, the width and height of the form will be displayed in the first TextCtrl. When FramePos is selected, the x and y coordinate positions of the form will be displayed in the first TextCtrl. By selecting the multiple selection button AllInfo, all three information of the form and mouse can be displayed in the second multiline TextCtrl.

# -*- coding: utf-8 -*-
"""
Created on 2021-12-21 10 a.m:54

@author: Smile drunk Red Mansions.(3303295829@qq.com)

@Software: PyCharm

(1) create by Smile drunk Red Mansions. 2021-12-21 10 a.m:54
"""
import wx

class TestCtrlFrame(wx.Frame):
    def __init__(self,superion):
        wx.Frame.__init__(self, parent=superion, title='My Frist Form')
        self.panel = wx.Panel(self)
        self.radioButtonFramePos = wx.RadioButton(self.panel, -1, 'FramePos:')
        self.radioButtonFrameSize = wx.RadioButton(self.panel, -1, 'FrameSize:')
        self.radioButtonMousePos = wx.RadioButton(self.panel, -1, 'MousePos:')
        self.checkBoxAllinfo = wx.CheckBox(self.panel, -1, 'AllInfo')

        self.label1 = wx.StaticText(self.panel, -1, 'FrameMouse', style=wx.ALIGN_LEFT)
        self.label2 = wx.StaticText(self.panel, -1, 'AllInfo', style=wx.ALIGN_LEFT)

        self.FrameMouse = wx.TextCtrl(self.panel, -1, "", style=wx.TE_READONLY)
        self.AllInfo = wx.TextCtrl(self.panel, -1, "", style=wx.TE_MULTILINE,size=(150,100))

        sizer1 = wx.FlexGridSizer(4, 2, 5, 5)
        sizer1.AddMany(
            [(self.radioButtonFramePos, 0, wx.EXPAND),
             (self.radioButtonFrameSize, 0, wx.EXPAND),
             (self.radioButtonMousePos, 0, wx.EXPAND),
             (self.checkBoxAllinfo, 0, wx.EXPAND),
             (self.label1, 0, wx.ALIGN_RIGHT),
             (self.FrameMouse, 0, wx.SHAPED),
             (self.label2, 0, wx.ALIGN_RIGHT),
             (self.AllInfo, 0, wx.SHAPED)])

        self.border = wx.BoxSizer(wx.VERTICAL)
        self.border.Add(sizer1, 0, wx.ALL, 80)
        self.panel.SetSizerAndFit(self.border)
        self.Fit()  # Form size adaptation

        self.Bind(wx.EVT_SIZE, self.OnSize)
        self.Bind(wx.EVT_MOVE, self.OnFrameMove)
        self.panel.Bind(wx.EVT_MOTION, self.OnMouseMove)

    def OnSize(self, event):
        self.size = event.GetSize()
        if self.radioButtonFrameSize.GetValue() == True:
            self.FrameMouse.SetValue("%s, %s" % (self.size.width, self.size.height))
        if self.checkBoxAllinfo.GetValue() == True:
            self.AllInfo.SetValue("Form size%s, %s\n Form position%s, %s\n Mouse position%s, %s" % (self.size.width, self.size.height,self.posFrameMove.x, self.posFrameMove.y,self.pos.x, self.pos.y))

    def OnFrameMove(self,event):
        self.posFrameMove = event.GetPosition()
        if self.radioButtonFramePos.GetValue() == True:
            self.FrameMouse.SetValue("%s, %s" % (self.posFrameMove.x, self.posFrameMove.y))
        if self.checkBoxAllinfo.GetValue() == True:
            self.AllInfo.SetValue("Form size%s, %s\n Form position%s, %s\n Mouse position%s, %s" % (self.size.width, self.size.height,self.posFrameMove.x, self.posFrameMove.y,self.pos.x, self.pos.y))

    def OnMouseMove(self, event):  # Mouse movement event handler
        self.pos = event.GetPosition()
        if self.radioButtonMousePos.GetValue() == True:
            self.FrameMouse.SetValue("%s, %s" % (self.pos.x, self.pos.y))
        if self.checkBoxAllinfo.GetValue() == True:
            self.AllInfo.SetValue("Form size%s, %s\n Form position%s, %s\n Mouse position%s, %s" % (self.size.width, self.size.height,self.posFrameMove.x, self.posFrameMove.y,self.pos.x, self.pos.y))


if __name__ == '__main__':
    app=wx.App()
    frame = TestCtrlFrame(None)
    frame.Show()
    app.MainLoop()



Experiment 2

Write code, select the radio button, check box and enter the required user name and password in the text box, and then click "OK" to pop up a message box to prompt for the input and selection, and open the chat window; Click the "Cancel" button to automatically clear the user's input, and set the radio button "Male" to the selected state by default.

# -*- coding: utf-8 -*-
"""
Created on 2021-12-21 10 a.m:45

@author: Smile drunk Red Mansions.(3303295829@qq.com)

@Software: PyCharm

(1) create by Smile drunk Red Mansions. 2021-12-21 10 a.m:45
"""
import wx
from CH9_GUI import ChatWND 

class Chat(wx.Frame):
    def __init__(self,superion):
        wx.Frame.__init__(self, parent=superion, title='wx GUI')
        self.panel = wx.Panel(self, wx.ID_ANY)
        self.panel.SetBackgroundColour('Green')

        self.radioButtonSexM = wx.RadioButton(self.panel, -1, 'Male')
        self.radioButtonSexF = wx.RadioButton(self.panel, -1, 'Female')
        self.checkBoxAdmin = wx.CheckBox(self.panel, -1, 'Aministrator')
        self.label1 = wx.StaticText(self.panel, -1, 'UserName:', style=wx.ALIGN_RIGHT)
        self.label2 = wx.StaticText(self.panel, -1, 'Password:', style=wx.ALIGN_RIGHT)

        self.textName = wx.TextCtrl(self.panel, -1)
        self.textPwd = wx.TextCtrl(self.panel, -1, style=wx.TE_PASSWORD)

        self.buttonOK = wx.Button(self.panel, -1, 'OK')
        self.buttonCancel = wx.Button(self.panel, -1, 'Cancel')
        sizer1 = wx.FlexGridSizer(1, 3, 5, 5)
        sizer1.AddMany(
            [(self.radioButtonSexM, 0, wx.EXPAND),
             (self.radioButtonSexF, 0, wx.EXPAND),
             (self.checkBoxAdmin, 0, wx.EXPAND), ])

        sizer2 = wx.FlexGridSizer(3, 2, 5, 5)
        sizer2.AddMany(
            [(self.label1, 0, wx.EXPAND),
             (self.textName, 0, wx.EXPAND),
             (self.label2, 0, wx.EXPAND),
             (self.textPwd, 0, wx.EXPAND),
             (self.buttonOK, 0, wx.EXPAND),
             (self.buttonCancel, 0, wx.EXPAND)])
        self.border = wx.BoxSizer(wx.VERTICAL)
        self.border.Add(sizer1, 0, wx.ALL, 15)
        self.border.Add(sizer2, 0, wx.ALL, 15)
        self.panel.SetSizerAndFit(self.border)
        self.Fit()  # Form size adaptation

        self.Bind(wx.EVT_BUTTON, self.OnButtonOK, self.buttonOK)
        self.Bind(wx.EVT_BUTTON, self.OnButtonCancel, self.buttonCancel)

    # def OnButtonOK(self, event):
    #     finalStr = ''
    #     if self.radioButtonSexM.GetValue() == True:
    #         finalStr += 'Sex:Male\n'
    #     elif self.radioButtonSexF.GetValue() == True:
    #         finalStr += 'Sex:Female\n'
    #     if self.checkBoxAdmin.GetValue() == True:
    #         finalStr += 'Administrator\n'
    #     if self.textName.GetValue() == 'yang' and self.textPwd.GetValue() == '123':
    #         finalStr += 'user name and password are correct\n'
    #     else:
    #         finalStr += 'user name or password is incorrect\n'
    #     wx.MessageBox(finalStr)

    def OnButtonCancel(self, event):
        self.radioButtonSexM.SetValue(True)
        self.radioButtonSexF.SetValue(False)
        self.checkBoxAdmin.SetValue(True)
        self.textName.SetValue('')
        self.textPwd.SetValue('')

    def OnButtonOK(self, event):
        finalStr = ''
        if self.radioButtonSexM.GetValue() == True:
            finalStr += 'Sex:Male\n'
        elif self.radioButtonSexF.GetValue() == True:
            finalStr += 'Sex:Female\n'
        if self.checkBoxAdmin.GetValue() == True:
            finalStr += 'Administrator\n'
        if self.textName.GetValue() == 'yang' and self.textPwd.GetValue() == '123':
            finalStr += 'user name and password are correct\n'
            wx.MessageBox(finalStr)
            frame = ChatWND.ChatWND(None)  # Create frame class object
            frame.Show(True)
            self.Destroy()
        else:
            finalStr += 'user name or password is incorrect\n'
            wx.MessageBox(finalStr)

if __name__ == '__main__':
    app=wx.App()
    frame = Chat(None)
    frame.Show()
    app.MainLoop()

Chat interface design (ChatWND.py)

# -*- coding: utf-8 -*-
"""
Created on 2021-12-21 10 a.m:54

@author: Smile drunk Red Mansions.(3303295829@qq.com)

@Software: PyCharm

(1) create by Smile drunk Red Mansions. 2021-12-21 10 a.m:54
"""
import wx

class ChatWND(wx.Frame):
    def __init__(self, superior):
        wx.Frame.__init__(self, parent=superior,title=u'Chat Window', size=(800, 600))
        self.panel = wx.Panel(self, wx.ID_ANY)
        self.panel.SetBackgroundColour("Green")

        self.label1 = wx.StaticText(self.panel, -1, 'IP:', style=wx.ALIGN_LEFT)
        self.label2 = wx.StaticText(self.panel, -1, 'PORT:', style=wx.ALIGN_RIGHT)
        self.label3 = wx.StaticText(self.panel, -1, 'MSG:', style=wx.ALIGN_LEFT, size=(50, 50))
        self.label4 = wx.StaticText(self.panel, -1, 'Send:', style=wx.ALIGN_LEFT, size=(50, 50))

        self.textIP = wx.TextCtrl(self.panel, -1)
        self.textPORT = wx.TextCtrl(self.panel, -1)
        self.textRecord = wx.TextCtrl(self.panel, -1, style=wx.TE_MULTILINE, size=(520, 200))
        self.textSend = wx.TextCtrl(self.panel, -1, style=wx.TE_MULTILINE, size=(520, 30))

        self.buttonConnectSvr = wx.Button(self.panel, -1, 'Connect')
        self.buttonSendMsg = wx.Button(self.panel, -1, 'Send')
        self.buttonGetFiles = wx.Button(self.panel, -1, 'File')

        sizer1 = wx.FlexGridSizer(2, 2, 20, 15)
        sizer1.AddMany(
            [
                (self.label3, 0, wx.ALIGN_LEFT),
                (self.textRecord, 0, wx.ALIGN_RIGHT),
                (self.label4, 0, wx.ALIGN_LEFT),
                (self.textSend, 0, wx.ALIGN_RIGHT),

            ])
        sizer2 = wx.FlexGridSizer(1, 7, 5, 5)
        sizer2.AddMany(
            [(self.label1, 0, wx.ALIGN_LEFT),
             (self.textIP, 0, wx.EXPAND),
             (self.label2, 0, wx.ALIGN_LEFT),
             (self.textPORT, 0, wx.ALIGN_RIGHT),
             (self.buttonConnectSvr, 0, wx.EXPAND),
             (self.buttonSendMsg, 0, wx.EXPAND),
             (self.buttonGetFiles, 0, wx.ALIGN_RIGHT)
             ])
        self.border = wx.BoxSizer(wx.VERTICAL)
        self.border.Add(sizer1, 0, wx.ALL, 15)
        self.border.Add(sizer2, 0, wx.ALL, 15)
        self.panel.SetSizerAndFit(self.border)
        self.Fit()  # Form size adaptation
if __name__ == '__main__':
    app=wx.App()
    frame = ChatWND(None)
    frame.Show()
    app.MainLoop()

Keywords: Python GUI Tkinter

Added by havenpets on Mon, 27 Dec 2021 10:09:39 +0200