One event handling and GUI programming. Graphical User Intefaces (GUIs) The standard...
-
Upload
archibald-reynolds -
Category
Documents
-
view
230 -
download
0
description
Transcript of One event handling and GUI programming. Graphical User Intefaces (GUIs) The standard...
one
event handlingand GUI programming
Graphical User Intefaces (GUIs) The standard window-and-mouse-based user interface
is called a graphical user interface As opposed to a command-line interface
(which looks more like programming)
Basic idea: make the program visible Show possible operations as visible objects
Menus, check boxes, sliders, etc. Display the state of the program visually
Progress bars and watch cursors when waiting Gray out menu items that can’t work
Minimize program state that affects the user Don’t require them to do thing A before they can do thing B
Toolkits and widget sets Libraries that implement typical GUI components
Menus (menu-bar and popup) Text boxes Sliders Check boxes Radio buttons List boxes
There are many different widget sets available for different operating systems Mac Toolbox, XTk, Windows Forms, Microsoft Avalon, MFC,
HTML forms (for the web), Swing, JDK, Flash, …
A simple widget: MessageBox [MessageBox.Show string title]
Makes a dialog box that says string and has title in its titlebar. Stops the program until the user hits the OK button
[MessageBox.Show string title buttons] Same, but you can choose the buttons that appear But you have to pick the available buttons from:
MessageBoxButtons.OK MessageBoxButtons.OKCancel MessageBoxButtons.RetryCancel MessageBoxButtons.YesNo MessageBoxButtons.YesNoCancel MessageBoxButtons.AbortRetryIgnore
Returns the button that the user pressed
The Windows Forms widget set
The GUI toolkit distributed with Microsoft .NET Each kind of component is a class
So you make them with [new classname args …] Each class has methods to find what its setting is, put
it on the screen, etc.
All the classes are subclasses of the überclass Control
Fields of the Control class These can be used to change the
appearance of any control
There are many more, but these should be enough for you for now.
BackColor, ForeColor Background/foreground color for the
control Font
Font that text appears in (see the slide at the end for how to specify a font)
Text Text that appears in the control (if any)
Height, Width The size of the control
Location The X,Y coordinate of the top-left
corner (as a point) Left, Top
The individual X- and Y- coordinates of the control within its window
The Form class A form is a window that
can hold controls
It’s also a special kind of control, so you can set things like its Width, Height, BackColor, etc.
[new Form] Makes a form
[form.Controls.Add control] Adds a control to a form
[Application.Run form] Displays form and lets the
user work with it until they close it.
The TextBox control
[new TextBox] Makes a space where the user can type Whatever they type appears in the Text field
of the object (remember the Text field?)
Example: entering text
[define get-text[starting-text → [with* f = [new Form] make the Form
tbox = [new TextBox] [f.Controls.Add tbox] [tbox.Text ← starting-text] [tbox.Width ← 150] [tbox.Location ← [point 10 10]] [Application.Run f] tbox.Text]]]
Example: entering text
[define get-text[starting-text → [with* f = [new Form]
tbox = [new TextBox] make the TextBox [f.Controls.Add tbox] [tbox.Text ← starting-text] [tbox.Width ← 150] [tbox.Location ← [point 10 10]] [Application.Run f] tbox.Text]]]
Example: entering text
[define get-text[starting-text → [with* f = [new Form]
tbox = [new TextBox] [f.Controls.Add tbox] add the TextBox to the Form [tbox.Text ← starting-text] [tbox.Width ← 150] [tbox.Location ← [point 10 10]] [Application.Run f] tbox.Text]]]
Example: entering text
[define get-text[starting-text → [with* f = [new Form]
tbox = [new TextBox] [f.Controls.Add tbox] [tbox.Text ← starting-text] set Text to the default [tbox.Width ← 150] [tbox.Location ← [point 10 10]] [Application.Run f] tbox.Text]]]
Example: entering text
[define get-text[starting-text → [with* f = [new Form]
tbox = [new TextBox] [f.Controls.Add tbox] [tbox.Text ← starting-text] [tbox.Width ← 150] make it 150 pixels wide [tbox.Location ← [point 10 10]] [Application.Run f] tbox.Text]]]
Example: entering text
[define get-text[starting-text → [with* f = [new Form]
tbox = [new TextBox] [f.Controls.Add tbox] [tbox.Text ← starting-text] [tbox.Width ← 150] [tbox.Location ← [point 10 10]] put tbox at (10, 10) [Application.Run f] tbox.Text]]]
Example: entering text
[define get-text[starting-text → [with* f = [new Form]
tbox = [new TextBox] [f.Controls.Add tbox] [tbox.Text ← starting-text] [tbox.Width ← 150] [tbox.Location ← [point 10 10]] [Application.Run f] let the user play with it tbox.Text]]]
Example: entering text
[define get-text[starting-text → [with* f = [new Form]
tbox = [new TextBox] [f.Controls.Add tbox] [tbox.Text ← starting-text] [tbox.Width ← 150] [tbox.Location ← [point 10 10]] [Application.Run f] tbox.Text]]] return the text they typed
Three problems This is okay, but it has some
definite problems: You click the close box to finish
(rather than an OK box)
It doesn’t actually work because Application.Run turns out to clear the Text of tbox
We’ll ignore this for the moment and pretend it works
The window is outrageously tall We’ll leave fixing this as an
exercise for the reader The window has no name
You can fix this by setting its Text or Name field
Adding a button
[define get-text[starting-text → [with* f = [new Form] b = [new Button]
tbox = [new TextBox] [f.Controls.Add tbox] [tbox.Text ← starting-text] [tbox.Width ← 150] [tbox.Location ← [point 10 10]] [f.Controls.Add b]
[b.Location ← [point 170 10]] [b.Text ← “OK”]
[Application.Run f] tbox.Text]]]
Trying it out Hey! We have a button!
Hey! It doesn’t do anything!
Hey! The window is still too tall and has no name! Oh, shut up…
Event handling
You need some way of specifying what to do when the button is pressed This is done by specifying a procedure called
an “event handler” or a “callback” When the even happens, the system calls the
procedure
Event handling in Meta
Events look like lists of procedures to call when the event happens To add a handler for an event, add it to the list:
[object.event.Add handler-procedure]
Windows Forms always passes two parameters to the handler procedure The control that generated the event An extra data object that we’ll ignore for the moment
Fixing it
…[f.Controls.Add b][b.Location ← [point 170 10]][b.Text ← “OK”][b.Click.Add [ignore ignore → [f.Close]]][f.Height ← 75][f.Text ← “Please enter some text”]…
Fixing it
…[f.Controls.Add b][b.Location ← [point 170 10]][b.Text ← “OK”]«Add a procedure to run whenever b is clicked»[b.Click.Add [ignore ignore → [f.Close]]][f.Height ← 75][f.Text ← “Please enter some text”]…
Fixing it
…[f.Controls.Add b][b.Location ← [point 170 10]][b.Text ← “OK”]«The procedure closes the form»[b.Click.Add [ignore ignore → [f.Close]]][f.Height ← 75][f.Text ← “Please enter some text”]…
Fixing it
…[f.Controls.Add b][b.Location ← [point 170 10]][b.Text ← “OK”][b.Click.Add [ignore ignore → [f.Close]]][f.Height ← 75] shorten the height of the form[f.Text ← “Please enter some text”]…
Fixing it
…[f.Controls.Add b][b.Location ← [point 170 10]][b.Text ← “OK”][b.Click.Add [ignore ignore → [f.Close]]][f.Height ← 75][f.Text ← “Please enter some text”] name it…
It works! In particular, clicking
the OK box Closes the form as if
the user had click the close box
Which causes Application.Run to finish
Which causes get-text to finish and return the text
The TrackBar control [new TrackBar]
Makes a slider control Useful fields (plus Control’s fields)
Value The current numeric value the user has chosen
Minimum, Maximum The numeric values for the ends of the range of the slider
TickFrequency How often to draw tick marks
Orientation Whether it should be a horizontal or vertical control.
Set it to either Orientation.Horizontal or Orientation.Vertical. Useful events
ValueChanged (called when the user moves the slider)
What does this do?[with f = [new Form]
r = [new TrackBar] g = [new TrackBar] b = [new TrackBar]
[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add
[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]] [list r g b]] [r.Top ← 10] [g.Top ← 60] [b.Top ← 110] [Application.Run f]]]
What does this do?[with f = [new Form] make a form
r = [new TrackBar] g = [new TrackBar] b = [new TrackBar]
[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add
[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]] [list r g b]] [r.Top ← 10] [g.Top ← 60] [b.Top ← 110] [Application.Run f]]]
What does this do?[with f = [new Form]
r = [new TrackBar] make three sliders to go with it g = [new TrackBar] b = [new TrackBar]
[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add
[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]] [list r g b]] [r.Top ← 10] [g.Top ← 60] [b.Top ← 110] [Application.Run f]]]
What does this do?[with f = [new Form]
r = [new TrackBar] g = [new TrackBar] b = [new TrackBar]
[for-each [slider → run this procedure on r, g, and b [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add
[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]] [list r g b]] [r.Top ← 10] [g.Top ← 60] [b.Top ← 110] [Application.Run f]]]
What does this do?[with f = [new Form]
r = [new TrackBar] g = [new TrackBar] b = [new TrackBar]
[for-each [slider → [f.Controls.Add slider] add it to the form [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add
[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]] [list r g b]] [r.Top ← 10] [g.Top ← 60] [b.Top ← 110] [Application.Run f]]]
What does this do?[with f = [new Form]
r = [new TrackBar] g = [new TrackBar] b = [new TrackBar]
[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] make it 255 pixels wide [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add
[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]] [list r g b]] [r.Top ← 10] [g.Top ← 60] [b.Top ← 110] [Application.Run f]]]
What does this do?[with f = [new Form]
r = [new TrackBar] g = [new TrackBar] b = [new TrackBar]
[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] set its limits to 0 and 255
[slider.Maximum ← 255] [slider.ValueChanged.Add
[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]] [list r g b]] [r.Top ← 10] [g.Top ← 60] [b.Top ← 110] [Application.Run f]]]
What does this do?[with f = [new Form]
r = [new TrackBar] g = [new TrackBar] b = [new TrackBar]
[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add add the following handler for when the slider changes
[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]] [list r g b]] [r.Top ← 10] [g.Top ← 60] [b.Top ← 110] [Application.Run f]]]
What does this do?[with f = [new Form]
r = [new TrackBar] g = [new TrackBar] b = [new TrackBar]
[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add
ignore arguments … and change the background color of the form [ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]]
[list r g b]] [r.Top ← 10] [g.Top ← 60] [b.Top ← 110] [Application.Run f]]]
What does this do?[with f = [new Form]
r = [new TrackBar] g = [new TrackBar] b = [new TrackBar]
[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add
[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]] [list r g b]] [r.Top ← 10] arrange the sliders [g.Top ← 60] [b.Top ← 110] [Application.Run f]]]
What does this do?[with f = [new Form]
r = [new TrackBar] g = [new TrackBar] b = [new TrackBar]
[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add
[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]] [list r g b]] [r.Top ← 10] [g.Top ← 60] [b.Top ← 110] [Application.Run f]]] start the form up
Running it
Fixing a bug[with f = [new Form]
r = [new TrackBar] g = [new TrackBar] b = [new TrackBar]
[for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add
[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]] [list r g b]] [r.Top ← 10] [g.Top ← 60] [b.Top ← 110] [Application.Run f]]]
This what it looks like when you start it up. What’s wrong with this?
Fixing a bug[with f = [new Form]
r = [new TrackBar] g = [new TrackBar] b = [new TrackBar]
[f.BackColor ← [color 0 0 0]] [for-each [slider → [f.Controls.Add slider] [slider.Width ← 255] [slider.Minimum ← 0] [slider.Maximum ← 255] [slider.ValueChanged.Add
[ignore ignore → [f.BackColor ← [color r.Value g.Value b.Value]]]]] [list r g b]] [r.Top ← 10] [g.Top ← 60] [b.Top ← 110] [Application.Run f]]]
What does this do?[define slider-text [→ [with f = [new Form] s = [new TrackBar] t = [new TextBox] [f.Controls.Add s] [f.Controls.Add t] [s.Top ← 10] [s.ValueChanged.Add [i i → [t.Text ← [s.Value.ToString]]]] [t.Top ← 60] [t.TextChanged.Add [i i → [s.Value ← [System.Int32.Parse t.Text]]]] [Application.Run f]]]]
Hints: [x.ToString] turns x into a string [System.Int32.Parse string] returns the number represented by string.
Example: [System.Int32.Parse “10”] returns 10 (the integer, not a string)
Fixing a bug[define slider-text[→ [with f = [new Form] s = [new TrackBar] t = [new TextBox] [f.Controls.Add s] [f.Controls.Add t] [s.Top ← 10] [s.ValueChanged.Add [i i → [t.Text ← [s.Value.ToString]]]] [t.Top ← 60] [t.TextChanged.Add [i i → [ignore-errors [→ [s.Value ← [System.Int32.Parse t.Text]]]]]] [Application.Run f]]]]
[ignore-errors procedure] runs procedure and returns its value. If it generates an error, it returns null rather than an error.
It works!
Some other useful Controls
[new Label] Like a textbox but the user can’t change it
[new CheckBox] Makes a box Useful fields
Checked (whether the box has been checked (true or false))
picky little details I ignored
Namespaces All global variables are stored in namespaces
The “proper” name for a variable is namespace.name where Name is the name of the variable Namespace is the name of the namespace
The system keeps track of your “current” namespace If the variable you’re using is in the current namespace, you can just
type its name That’s why you haven’t had to type namespace.name much before
The system also keeps track of a set of namespace that you’re “using”
You also don’t have to the the namespace prefix if the variable is in one of the namespaces you’re using.
To use a namespace, type: [using namespace]
Using Windows Forms All the Controls we showed you are in the
namespace System.Windows.Forms That means the “real” name of TrackBar is
System.Windows.Forms.TrackBar But you can get around having to type that by starting
out your program with:[using System.Windows.Forms]
It also turns out we used some classes in the namespace System.Drawing. So you can run all the code in here by typing:
[using System.Windows.Forms System.Drawing]
How do I specify a font?Just type:
[new Font fontfamily [System.Convert.ToSingle size] style]
where:
Fontfamily is a string, like “Times New Roman” Size is a number (the size of the font in points), e.g. 10 or 12 Style is one of:
FontStyle.Regular, FontStyle.Bold, FontStyle.Italic, FontStyle.Strikeout, FontStyle.Underline
How do we fix get-text to return the stupid text? Change:[with* f = [new Form] b = [new Button] tbox = [new TextBox]
… bla bla bla …
[Application.Run f] tbox.Text]
To:[with* f = [new Form] b = [new Button] tbox = [new TextBox] remember = starting-text
… bla bla bla …
[tbox.TextChanged.Add [ignore ignore → [remember ← tbox.Text]]]
[Application.Run f] remember]
We add a new event handler that runswhenever the user changes the text