Журнал LinuxFormat - перейти на главную

LXF72:Gambas

Материал из Linuxformat
Перейти к: навигация, поиск

Содержание

Модули и классы

ЧАсТь 2 Пусть это будет нашим маленьким секретом: программирование — это действительно просто. Доктор Марк Александр Бейн (Dr Mark Alexander Bain) укажет вам путь наименьшего сопротивления.

Полагаю, весь прошедший месяц вы плотно занимались работой с базами данных, впечатляя своего босса, своих коллег и даже собственную кошку своими способностями в добыче данных, обработке их и отправке обратно в базу (конечно же, вы отметили про себя, что Gambas делает это занятие невероятно простым).

Технологии, с которыми мы имели дело до сих пор, хороши для одиночных, небольших приложений, однако пришло время узнать, как можно работать с Gambas в больших проектах. Должно быть, в первую очередь вы захотите узнать, как можно открыть больше одной формы. Вот этим-то мы сейчас и займемся.

начнем с чистого проекта. щелкните New Project (Создать проект) на экране приветствия Gambas, или в меню File (Файл) выберите New Project (Создать проект), если Gambas уже открыт. затем, добавьте две новые чистые формы (правой кнопкой мыши щелкните Forms (Формы) в окне проекта, затем выберите New (Создать) > Form (Форму). не поддавайтесь искушению оставить имена как есть (по умолчанию формы будут названы Form1 и Form2). Этим вы только создадите себе проблемы в дальнейшем: если будут получены десятки форм с подобными названиями, то произойдет полная неразбериха. Так что, возьмите себе за правило называть их сразу какими-либо осмысленными именами — в нашем случае, например, frmMain и frmLogon.

РАботА с несКоЛьКиМи ФоРМАМи

Теперь у вас есть две чистые формы, между которыми можно переключаться в режиме дизайна. однако, никаких действий эти формы пока совершать не могут. Первоочередная задача — добавить кнопку выхода, чтобы любую форму можно было закрыть. Перейдите к frmMain и создайте новую кнопку, кликнув значок кнопки в окне инструментов и перетащив его на форму. нажмите F4 для перехода в окно Properties (Свойства), и измените текст на кнопке на «Close» («закрыть»).

Так же, как с формами, заведите привычку давать кнопкам осмысленные имена вместо того, чтобы оставлять их названия такими, какие они берут себе сами (Button 1, Button 2 и т. д.). Воспользуйтесь окном Properties (Свойства), чтобы изменить название закрывающей кнопки на btnClose. затем дважды щелкните по новой кнопке, чтобы добавить код для обработки ее нажатия. он будет выглядеть примерно так:

‘ Gambas class file
PUBLIC SUB btnClose_Click()
ME.Close
END

Повторив весь процесс для формы frmLogon, вы получите возможность закрывать обе формы. Конечно, для того чтобы закрыть frmLogon, вам необходимо будет сначала ее открыть, так как к этому моменту доступна только frmMain (попробуйте запустить проект и посмотрите, что произойдет). очевидно, следующей задачей должно стать добавление на форму frmMain кнопки, которая позволила бы перейти к frmLogon.

В режиме дизайна перейдите к frmMain и добавьте новую кнопку. Воспользуйтесь окном Properties (Свойства) для изменения текста кнопки на «Log On» («Вход»), а ее названия на btnLogon.

Прежде чем приступить к написанию кода, мы должны сначала подумать, в каком режиме будет открываться форма frmLogon. Если вы работали в среде Visual Basic, вам должно быть знакомо понятие открытия форм в модальном и немодальном режимах. Когда форма frmLogon открывается в немодальном режиме, вы можете получить доступ к одной форме независимо от другой. Если же вы откроете frmLogon модально, то перейти от нее обратно к frmMain можно будет только закрыв frmLogon.

Дважды щелкнув btnLogon, вы получите примерно это:

PUBLIC SUB btnLogon_Click()
END

Вы можете ввести

frmLogon.Show

или

frmLogon.ShowModal

Если мы вызываем btnLogon немодально, то можно добавить на frmLogon кнопку для вызова frmMain. Убедитесь, что вы используете только немодальный вызов (Show вместо ShowModal). Если вы установите обе формы в модальный режим — ваше приложение намертво зависнет (если поразмыслить — это очевидно), поэтому будьте внимательны!

Если вы добавили все нужные формы и полностью закончили переходы между ними, давайте узнаем, как можно передавать данные.

ЛоКАЛьные и гЛобАЛьные ДАнные

В этом примере мы используем две формы, frmMain и frmLogon. У нас могут быть данные, которые имеют отношение либо только к frmMain, либо только к frmLogon — локальные данные. но могут существовать и другие данные, доступ к которым может потребоваться в пределах всего приложения — глобальные данные.

ниже приведен код для frmLogon с добавленной на нее кнопкой btnLogon:

‘ Gambas class file
logged_on AS Boolean
countdown AS Integer
PUBLIC SUB btnClose_Click()
ME.Close
END
PUBLIC SUB Form_Open()
logged_on = FALSE
countdown = 3
END
PUBLIC SUB btnLogon_Click()
logged_on = TRUE
countdown = countdown - 1
END

Мы видим, что переменные описаны в самом начале. затем они инициализируются при открытии формы (Form_Open) и изменяются при щелчке по кнопке «Log On» («Вход») (btnLogon_Click). При таком описании переменных они являются локальными по отношению к frmLogon. Если же некоторые из них необходимо сделать доступными для всего остального приложения, то их нужно описать как PUBLIC:

PUBLIC logged_on AS Boolean
PUBLIC countdown AS Integer

описав переменные logged_on и countdown как глобальные, можно использовать их вне формы frmLogon. например, можно будет добавить новую кнопку (btnCheckStatus) на frmMain со следующим исполняемым кодом:

PUBLIC SUB btnCheckStatus_Click()
IF (frmLogon.logged_on = FALSE) THEN
message (“You are not logged on. “ &
frmLogon.countdown & “ attempts left”)
ELSE
message (“Logged On”)
END IF
END

заметьте, что вы должны предварять имя переменной именем формы (как, например, frmLogon.logged_on). однако, это верно только до тех пор, пока frmLogon открыта. Можно заметить, что countdown будет равна 0, пока frmLogon не откроется, 3 — когда она будет открыта, и 0 — когда снова закроется. очевидно, это хорошо только если frmLogon будет постоянно открыта. В противном случае, нужно поискать другой путь.

По мере роста проекта может проявиться еще одно неудобство. Метод, описанный выше, позволяет обращаться к глобальным данным, содержащимся только в Form1, Form2 и т. д., но не к более общим данным. Это может вызвать неразбериху: нужно постоянно помнить, где содержатся данные, к тому же для их правильной инициализации необходимо открывать формы только в определенном порядке.

Гораздо более эффективным методом представляется создание модуля для хранения глобальных параметров. Модуль также может использоваться как отправная точка — для инициализации данных, а также для того чтобы предохранить нас от неприятных ситуаций, одну из которых мы только что наблюдали. Для создания модуля щелкните правой кнопкой мыши окно проекта и выберите New > Module (Создать > Модуль). В появившемся затем окне измените имя на Global («Глобальный»). здесь же следует отметить галочкой параметр Startup Class (если вы забыли сделать это, не волнуйтесь — галочку можно поставить после создания файла).

Теперь перейдем к новому модулю и отредактируем его вот так:

‘ Gambas module file
PUBLIC logged_on AS Boolean
PUBLIC countdown AS Integer
PUBLIC SUB Main()
logged_on=FALSE
countdown=3
frmMain.Show
END

Если модуль Global («Глобальный») определен как Startup Class, то при запуске проекта он автоматически выполняет главную подпрограмму (Main subroutine). При этом инициализируются все требуемые параметры, после чего отображается та форма, которую мы хотим видеть первой.

Теперь обе формы будут следует отредактировать с учетом нового расположения параметров (они теперь определены в модуле Global («Глобальный»), а не в frmLogon):

‘frmMain
Gambas class file
PUBLIC SUB btnClose_Click()
ME.Close
END
PUBLIC SUB btnLogon_Click()
frmLogon.Show
END
PUBLIC SUB Form_Open()
END
PUBLIC SUB btnCheckStatus_Click()
IF (Global.logged_on = FALSE) THEN
message (“You are not logged on. “ &
Global.countdown & “ attempts left”)
ELSE
message (“Logged On”)
END IF
END

и

‘frmLogon
‘ Gambas class file
PUBLIC SUB btnClose_Click()
ME.Close
END
PUBLIC SUB Form_Open()
END
PUBLIC SUB btnLogon_Click()
Global.logged_on=TRUE
Global.countdown=Global.countdown - 1
END

Когда вы запустите проект, то увидите, что все параметры установлены корректно, и они будут оставаться таковыми в процессе работы.

ПовтоРное исПоЛьзовАние КоДА

одной из причин, по которым я начал заниматься программированием профессионально, была обыкновенная лень. я понял, что компьютер может сделать за меня кучу дел, предоставив мне просто наслаждаться жизнью. но помните — никто (особенно ваш босс) не должен знать, насколько все это просто.

С кодированием происходит точно так же. Наша задача — выполнить как можно больше работы, прилагая как можно меньше усилий со своей стороны. З десь самое место для повторного использования кода. Под повторным использованием кода я понимаю не вырезание и вставку кода из одного окна в другое — я имею в виду физическое использование кода, который однажды уже был написан.

Если вы следовали руководству предыдущего номера, у вас должен быть проект доступа к базам данных (если у вас его нет — не волнуйтесь, код есть на прилагаемом диске). Сейчас мы увидим, как легко можно повторно использовать форму из этого проекта.

Щелкните правой кнопкой мыши на проекте и выберите New > Form (Создать > Форму). Появится окно новой формы. Кликните вкладку Existing (Существующие), затем перейдите к тому месту, где вы сохранили проект базы данных. Выберите Form1.form. Мы видим, что к нашему проекту была добавлена новая форма. О на еще не готова к использованию, для этого нужен один из дополнительных компонентов Gambas. Перейдем к окну проекта и выберем Project > Properties (Проект > Свойства). Перейдем на вкладку Components (Компоненты) и отметим галочкой параметр gb.db. Теперь форма готова к использованию в нашем проекте.

Нам осталось только добавить кнопку (btnDbForm) и написать для нее следующий код:

PUBLIC SUB btnDbForm_Click()
Form1.Show
END

Если база данных запущена и работает, а таблицы настроены верно, то вы без лишних хлопот получите полнофункциональную форму.

МОДУЛЬ «НАПРОКАТ»

Такой метод повторного использования весьма удобен, но ограничен. Возможность подключиться к базе данных — это великолепно, но вам могут понадобиться другие Б Д, или вы не захотите использовать те формы, что были созданы прежде. Вот здесь-то модули берут свое. Точно так же, как мы создавали модули для установки глобальных параметров, можно создать модуль, с функциональностью базы данных.

Очевидно, первое, что предстоит сделать — это создать новый модуль. Н а этот раз назовем его Database (База данных), но не будем отмечать как Startup Class (модуль Global по-прежнему останется таковым). Х отя я и писал, что повторное использование кода — это не просто вырезание и вставка из одного окна в другое, сейчас мы сделаем именно это. Но только однажды. Обещаю. Мы хотим взять от формы БД всю функциональность, оставив черты, присущие этой, отдельно взятой, форме. Когда мы закончим, модуль Б Д будет выглядеть примерно так:

‘ Gambas module file
PUBLIC conn AS NEW Connection
PRIVATE connected AS Boolean
PUBLIC FUNCTION make_connection() AS Boolean
IF (connected = FALSE) THEN
WITH conn
.Type = “mysql”
.Host = “localhost”
.Login = “bainm”
.Password = “mypassword”
.Name = “customers”
END WITH
TRY conn.Open
IF ERROR THEN
Message (“Cannot Open Database. Error = “ & Error.Text)
RETURN FALSE
END IF
connected=TRUE
END IF
RETURN connected
END

Вы, наверное, заметили переменную connected, добавленную мною в код. Это сделано для того, чтобы не было попыток подключиться к базе данных, если подключение уже существует.

Теперь этот модуль доступен для всех создаваемых вами проектов. Просто добавьте его к проекту таким же образом, каким вы добавляли существующие формы (не забудьте отметить компонент gb.db.)

РАБОТА С КЛАССАМИ

Стойте, не уходите!. Не спешите — все не так заумно, как кажется. В действительности, не замечая этого, вы уже работали с классами в Gambas, только назывались они формами.

Давайте начнем с простого примера. Во-первых, создайте новый проект, чтобы иметь перед собой чистое рабочее место. Щелкните правой кнопкой мыши в окне проекта и выберите New > Class (Создать > Класс). Н азовите ваш новый класс Person (Лицо) (понимаете, к чему мы клоним?). Этому классу необходимы несколько ключевых элементов. Прежде всего, необходимо описать все переменные:

‘ Gambas class file
PUBLIC firstname AS String
PUBLIC surname AS String
PUBLIC salary AS Float

Здесь есть одна существенная подпрограмма, _new. О на нужна для инициализации всех переменных, которые относятся к классу:

PUBLIC SUB _new (OPTIONAL ifirstname AS
String,OPTIONAL isurname AS String,OPTIONAL isalary AS
Float)
firstname=ifirstname
surname=isurname
salary=isalary
END

В итоге, все функции и подпрограммы, относящиеся к классу, должны быть определены. Помните, что их нужно определять как PUBLIC, чтобы дать возможность внешним источникам (таким, как формы) обращаться к ним.

В этом случае, мы разработаем некий налоговый диапазон:

PUBLIC FUNCTION tax() AS Float
tsalary AS Float
ttax AS Float
tsalary = salary
ttax = 0
‘High band
IF (tsalary > 32400) THEN
ttax=(tsalary-32400)*40/100
tsalary = 32400
END IF
‘Middle band
IF (tsalary > 2090) THEN
ttax=ttax + (tsalary-2090)*22/100
tsalary=2090
END IF
‘Lower band
ttax=ttax + tsalary*10/100
RETURN ttax
END

Теперь класс можно использовать в приложении. Просто создайте форму, добавьте на нее заготовку таблицу (gridbox), назовите grdSalary, затем отредактируйте ее для придания нужной функциональности.

Первое, что нужно сделать, это описать переменные, которые будут относиться к экземплярам класса Person:

‘ Gambas class file
p1 AS Person
p2 AS Person

затем используем подпрограмму Form_Open для создания объектов (p1 и p2). Это можно сделать двумя различными способами. Первый вариант — передать параметры через оператор NEW; другой — создать объект, затем присвоить значения его поляем:

PUBLIC SUB Form_Open()
p1 = NEW Person(“Jane”,”Jones”,35000)
p2 = NEW Person
WITH p2
.firstname=”Fred”
.surname=”Smith”
.salary=23000
END WITH

остаток подпрограммы состоит из заполнения таблицы (grdSalary) конкретными значениями для каждого объекта:

grdSalary.Columns.Count = 3
grdSalary.Rows.Count = 3
grdSalary.Current.Text = “First Name”
grdsalary.column = 1
grdSalary.Current.Text = “Surname”
grdsalary.column = 2
grdSalary.Current.Text = “Tax”
grdsalary.row =1
grdsalary.column = 0
grdSalary.Current.Text=p1.firstname
grdsalary.column = 1
grdSalary.Current.Text=p1.surname
grdsalary.column = 2
grdSalary.Current.Text=p1.tax()
grdsalary.row =2
grdsalary.column = 0
grdSalary.Current.Text=p2.firstname
grdsalary.column = 1
grdSalary.Current.Text=p2.surname
grdsalary.column = 2
grdSalary.Current.Text=p2.tax()
END

Да, конечно — не забудьте добавить обязательную кнопку выхода:

PUBLIC SUB btnClose_Click()
ME.Close
END

работа с классами оказалась совсем несложной, не так ли? Вы согласны с этим? Тогда ничто не мешает пользоваться ими. Это намного облегчит вашу работу по кодированию.

ЛюбАя бАзА, в ЛюбоМ Месте

Взгляните на следующий, думаю, даже более полезный пример. Мы разработали модуль для простого подключения к базе данных. однако, мы, очевидно, предполагаем, что можем сделать только одно подключение. А что если нам необходимо подключиться более чем к одной базе данных? здесь-то и проявит себя наша техника. Мы можем поступить еще более разумно, чем использовать модуль. Мы можем создать класс и использовать экземпляры класса для каждой базы данных. Конечно же, при этом нужно стремиться к тому, чтобы писать как можно меньше излишнего кода.

откройте новый проект и добавьте только что созданный модуль данных. затем, добавьте новый класс, назвав его dbConnection:

‘ Gambas class file
PUBLIC conn AS NEW Connection
PUBLIC connected AS Boolean
PUBLIC SUB _new ( OPTIONAL mtype AS String =
“mysql”,OPTIONAL mhost AS String = “localhost”,OPTIONAL
mdb AS String = “customers”,OPTIONAL m_id AS String =
“bainm”,OPTIONAL mpwd AS String = “mypassword”)
IF (connected = FALSE) THEN
WITH conn
.Type = mtype
.Host = mhost
.Login = m_id
.Password = mpwd
.Name = mdb
END WITH
TRY conn.Open
IF ERROR THEN
Message (“Cannot Open Database. Error = “ & Error.Text)
END IF
connected=TRUE
END IF
END

Теперь вы можете подключиться к любой базе данных:

mydb AS dbConnection
mydb2 AS dbConnection
PUBLIC SUB Form_Open()
mydb = NEW dbConnection
mydb2 = NEW dbConnection(“postgresql”,”http://www.myhost.com”,”maindb”)
END

Это был краткий рассказ о переменных, модулях и классах. однако, надеюсь, он был достаточно полон, чтобы понять, насколько они могут быть полезны. Просто помните золотое правило программиста — быть ленивым выгодно.

Персональные инструменты
купить
подписаться
Яндекс.Метрика