Ниже создается форма с владками, которая предназначена для использования в двух режимах — режиме просмотра информации о члене семьи и в режиме добавления сведений о члене семьи, информация о котором отсутствует в базе данных. В режиме просмотра не допускается изменение данных, в режиме добавления все поля доступны для ввода данных. В первом случае форма содержит три вкладки, во втором две.
Создадим форму ).
(рис 5.1) Редактор формы tabForm
Для всех якорей привязки выберем значение True. Закроем редактор формы и выберем команду компиляции пакета tabForm.pack.
Форма с вкладками открывается при нажатии на кнопку "Открыть" окна familyForm. Она отображает информацию о выделенном в списке члене семьи, поэтому предварительно следует найти и запомнить указатель на объект класса person, в котором хранится информация об этом человеке.
Откроем редактор формы familyForm, выделим кнопку "Открыть", перейдем на вкладку Events окна свойств и добавим обработчик события нажатия на кнопку ClickResponder. Ниже приведено определение предиката onViewClick.
predicates
onViewClick : button::clickResponder.
clauses
onViewClick(_Source) = button::defaultAction:-
Person = getSelectedPerson(),
!,
db:selectedPerson := some(Person),
familyForm := This,
Form = tabForm::display(getParent()),
Form:setText(Person:legend()).
onViewClick(_Source) = button::defaultAction.
Предикат getParent в данном случае возвращает указатель на класса taskWindow. Вместо него можно использовать предикат applicationWindow::get/0, который всегда возвращает указатель на объект класса taskWindow.
Итак, при нажатии на кнопку "Открыть" сначала находится указатель на объект выделенного элемента списка, затем он запоминается, далее запоминается указатель на объект окна familyForm, после этого открывается форма с вкладкамии и в ее строку заголовка записывается имя выделенного члена семьи.
Далее создаются страницы вкладок.
Выделим папку ):
надписи (Static Text) "Имя", "Фамилия", "Отец", "Мать";
поля редактирования (Edit Control):
Name: name_ctl; Text: <пустое поле>; Name: surname_ctl; Text: <пустое поле>;
групповой блок (Group Box):
Representation: Fact Variable; Name: sex_ctl; Text: Пол;
далее нужно выделить групповой блок и разместить в нем переключатель (Radio Button):
Name: male_ctl; Text: мужской; RadioState: checked;
затем нужно опять выделить групповой блок и разместить в нем еще один переключатель:
Name: female_ctl; Text: женский;
два выпадающих списка (List Button):
Name: father_ctl; Rows: 3; Name: mother_ctl; Rows: 3;
надпись (Static Text):
Representation: Fact Variable; Name: spouseText_ctl; Text: Супруги;
список (List Box):
Name: spouses_ctl; MultiSelect: True;
пользовательский элемент управления (Custom Control):
Class: pictControl (или imageControl для пользователей CE);
четыре кнопки (Push Button):
Name: left_ctl; Text: <; Enabled: False;
Name: right_ctl; Text: >; Enabled: False;
Name: del_ctl; Text: -; Enabled: False; Visible: False; TooltipText: tip("Удалить");
Name: browse_ctl; Text: …; Visible: False.
По умолчанию свойство Representation групповых блоков (Group Box) и надписей (Static Text) имеет значение Variable. Для группового блока "Пол" и надписи "Супруги" его значение следует изменить на Fact Variable (см. выше).
(рис 5.2) Редактор окна infoPage
Переключатель (Radio Button) может находиться в двух состояниях — checked (включен) и unchecked (выключен). Из набора переключателей, объединенных в одну группу, может быть включен только один переключатель.
Первые две кнопки используются для просмотра изображений. Третья кнопка предназначена для удаления изображения, четвертая кнопка — для добавления изображений. В режиме просмотра видимыми являются только две кнопки, предназначенные для просмотра изображений. Свойству Visible остальных кнопок устанавливается значение False (по умолчанию оно равно True). Для третьей кнопки создана подсказка (tooltip), которая появляется при наведении курсора на кнопку (аналогичные подсказки можно сделать для других элементов управления).
Для отображения родителей используются выпадающие списки, так как в режиме добавления в них помещаются списки членов семьи, из которых затем выбираются родители.
Надпись "Супруги" и список (супругов) становятся невидимыми в режиме просмотра, если в базе данных отсутствуют сведения о супругах члена семьи. Надпись меняется на "Супруг" или "Супруга", если член семьи имел (или имеет) ровно одного супруга или супругу.
Далее нужно закрыть редактор окна.
Аналогично следует создать в отдельных пакетах еще две страницы вкладок — treePage (Title: Деревья) и descrPage (Title: Описание). Эти страницы будут заполнены позднее.
В интерфейсе tabForm следует объявить свойство familyForm. Оно используется для хранения указателя на объект окна, из которого открывается форма с вкладками (может быть открыто несколько таких окон).
properties
familyForm : familyForm.
Теперь необходимо изменить определение конструктора new/1 в имплементации класса tabForm. В нем создаются страницы вкладок.
clauses
new(Parent):-
formWindow::new(Parent),
generatedInitialize(),
%
familyForm := familyForm::familyForm,
Page1 = tabPage::new(),
Tab1 = infoPage::new(Page1:getContainerControl()),
Page1:setText(Tab1:getText()),
tabControl_ctl:addPage(Page1),
if some(_) = familyForm:db:selectedPerson then
Page2 = tabPage::new(),
Tab2 = treePage::new(Page2:getContainerControl()),
Page2:setText(Tab2:getText()),
tabControl_ctl:addPage(Page2)
end if,
Page3 = tabPage::new(),
Tab3 = descrPage::new(Page3:getContainerControl()),
Page3:setText(Tab3:getText()),
tabControl_ctl:addPage(Page3),
infoPage := Tab1.
facts
familyForm : familyForm.
infoPage : infoPage.
Страница с деревьями отображается только в режиме просмотра сведений.
Заполним первую страницу вкладок. В интерфейсе infoPage следует объявить свойство, которое хранит указатель на объект базы данных, а также предикат updatePicture, который инициирует перерисовку изображения при изменении размеров формы.
properties
db : dbrel.
predicates
updatePicture: ().
В имплементации infoPage следует внести изменения в определение конструктора new, объявить необходимые факты-переменные и определить предикат updatePicture.
clauses
new():-
userControlSupport::new(),
generatedInitialize(),
db := familyForm::familyForm:db.
facts
db : dbrel := erroneous. % указатель на объект БД
pictures : string* := []. % имена файлов с изображениями
n : positive := 0. % количество изображений
k : positive := 0. % номер текущего изображения
clauses
updatePicture():-
pictControl_ctl:invalidate().
Теперь следует добавить обработчик события ShowListener. Когда открывается окно, заполняются поля страницы.
clauses
onShow(_Source, _Data):-
some(Person) = db:selectedPerson,
!,
name_ctl:setText(Person:name),
surname_ctl:setText(Person:surname),
setSex(Person:sex),
setParent(Person:idfather, father_ctl),
setParent(Person:idmother, mother_ctl),
setSpouses(Person),
setPictures(Person),
setEnable(Person:status).
onShow(_Source, _Data).
Ниже приведено определение предикатов, которые размещают сведения в элементах управления.
predicates
setSex: (string Sex).
setCheckedState: (radioButton).
clauses
setSex(dbrel::male):- !,
setCheckedState(male_ctl).
setSex(_):-
setCheckedState(female_ctl).
setCheckedState(RadioCtl):-
RadioCtl:setRadioState(radioButton::checked).
predicates
setParent: (unsigned Id, listButton).
clauses
setParent(ParentId, ListCtl):-
Person = db:getPerson(ParentId),
!,
ListCtl:addAt(0, Person:legend()),
ListCtl:selectAt(0, true).
setParent(_ParentId, _ListCtl).
predicates
setSpouses: (person).
clauses
setSpouses(Person):-
L = [S:legend() || I in Person:spouses, S = db:getPerson(I)],
L <> [],
!,
spouses_ctl:clearAll(),
spouses_ctl:addList(L),
spouseText_ctl:setText(spouseText(Person, L)).
setSpouses(_Person):-
spouses_ctl:setVisible(false),
spouseText_ctl:setText("").
predicates
spouseText: (person, string*) -> string.
clauses
spouseText(_Person, SpouseList) = "Супруги":-
[_, _| _] = SpouseList,
!.
spouseText(Person, _SpouseList) = "Супруга":-
dbrel::male = Person:sex,
!.
spouseText(_Person, _SpouseList) = "Супруг".
predicates
setPictures: (person).
clauses
setPictures(Person):-
pictures := Person:pictures,
n := list::length(pictures),
right_ctl:setEnabled(toBoolean(n > 1)),
[FileName | _] = pictures,
!,
pictControl_ctl:drawPict(FileName).
setPictures(_Person).
predicates
setEnable: (string Status).
clauses
setEnable("просмотр"):- !,
name_ctl:setReadOnly(),
surname_ctl:setReadOnly(),
sex_ctl:setEnabled(false).
setEnable(_):-
remove_ctl:setVisible(true),
browse_ctl:setVisible(true),
del_ctl:setVisible(true).
Если окно открывается в режиме просмотра, то сведения, которые в нем отображаются, изменять нельзя (см. определение предиката setEnable/1).
Как отмечалось выше, если сведения о супругах отсутствуют в базе данных, то список не отображается (рис. 5.3 рис 5.3).
(рис 5.3) Просмотр первой страницы вкладокДля члена семьи в базе данных может храниться несколько изображений (см. п. 4.1.1 ). Просмотр изображений выполняется с помощью кнопок ">" (вперед) и "<" (назад). Включение и выключение этих кнопок определяется количеством изображений.
Добавим обработчики событий нажатия на кнопки left_ctl и right_ctl. Определение этих предикатов приведено ниже.
clauses
onLeftClick(_Source) = button::defaultAction:-
k > 0,
!,
k := k - 1,
pictControl_ctl:drawPict(list::nth(k, pictures)),
if 0 = k then
left_ctl:setEnabled(false)
end if,
if n – 2 = k, n > 1 then
right_ctl:setEnabled(true)
end if.
onLeftClick(_Source) = button::defaultAction.
clauses
onRightClick(_Source) = button::defaultAction:-
k < n - 1,
!,
k := k + 1,
pictControl_ctl:drawPict(list::nth(k, pictures)),
if n - 1 = k then
right_ctl:setEnabled(false)
end if,
if 1 = k, n > 1 then
left_ctl:setEnabled(true)
end if.
onRightClick(_Source) = button::defaultAction.
Наконец, в редакторе формы tabForm следует добавить обработчик событий SizeListener и определить его так, как показано ниже.
clauses
onSize(_Source):-
infoPage:updatePicture().
Ниже приводится пример использования класса sciLexer для просмотра и редактирования заметок о членах семьи.
Вторая страница вкладок будет заполнена позднее (в главе 6 ). Приступим к заполнению третьей страницы (рис. 5.4 рис 5.4).
(рис 5.4) Редактор страницы descrPage
Откроем редактор страницы ):
пользовательский элемент управления (Class: sciLexer; Border: True);
три кнопки:
Name: open_ctl; Text: Открыть; Name: save_ctl; Text: Сохранить; Name: saveInDb_ctl; Text: Записать.
Закроем редактор формы.
Откроем файл descrPage.pro и изменим определение конструктора new так, как показано ниже. Кроме этого, объявим факты-переменные для хранения указателя на объект базы данных, имени файла и указания на систему кодирования символов в этом файле (Unicode или нет).
clauses
new():-
userControlSupport::new(),
generatedInitialize(),
%
db := familyForm::familyForm:db,
postAction({ :-
sciLexer_ctl:wrapMode := sciLexer_native::sc_wrap_word
}).
facts
db : dbrel.
filename : string := "".
isUnicode : boolean := false.
Предикат postAction используется в данном случае для того, чтобы после выведения текста к нему была применена операция автоматического переноса слова на следующую строку, если оно не помещается в поле окна целиком.
Далее следует добавить в редакторе окна descrPage обработчик события ShowListener и обработчики нажатия на кнопки "Открыть" и "Сохранить".
Ниже приведено определение предиката onShow. Когда открывается страница "Описание", в ней отображается текст из файла, указанного в базе данных.
clauses
onShow(_Source, _Data):-
some(Person) = db:selectedPerson,
[FileName | _] = Person:descriptions,
FilePath = dbrel::descriptionsFolder(),
FullName = fileName::setPath(FileName, FilePath),
try Text = file::readString(FullName, _)
catch Error do
stdio::writef("Error %. Unable to read from %.\n",
Error, FullName),
fail
end try,
!,
sciLexer_ctl:text := Text.
onShow(_Source, _Data).
Свойство text текстового редактора хранит текущий текст.
Текстовый редактор обладает большим количеством свойств (см. в Help страницу Interface sciLexerBase). Например, установить свойство "Только для чтения" можно следующим образом:
sciLexer_ctl:readOnly := true.
При нажатии кнопки "Открыть" открывается окно "Открыть файл". Содержимое выбранного в нем текстового файла отображается в окне.
clauses
onOpenClick(_Source) = button::defaultAction:-
StartPath = dbrel::descriptionsFolder(),
FileName = vpiCommonDialogs::getFileName("*.txt",
["Текстовый файл", "*.txt", " Document Word", "*.doc"],
"Открыть файл", [], StartPath, _),
!,
Text = file::readString(FileName, Mode),
isUnicode := Mode,
filename := FileName,
sciLexer_ctl:text := Text.
onOpenClick(_Source) = button::defaultAction.
При нажатии кнопки "Сохранить" открывается окно "Сохранить файл". Содержимое поля записывается в выбранный файл.
clauses
onSaveClick(_Source) = button::defaultAction:-
Text = string::trim(sciLexer_ctl:text),
Text <> "",
StartPath = dbrel::descriptionsFolder(),
FileName = vpiCommonDialogs::getFileName("*.txt",
["Текстовый файл", "*.txt", "Document Word", "*.doc"],
"Сохранить как", [dlgfn_save], StartPath, _),
!,
file::writeString(Filename, Text, isUnicode),
filename := FileName.
onSaveClick(_Source) = button::defaultAction.
Считать текст можно также следующим образом:
Text = sciLexer_ctl:getText().
Предикат обработки события нажатия на кнопку "Запомнить " будет определен позднее.
Упражнения
5.1. Создайте окно, содержащее два списка и кнопку. В первом списке должны быть перечислены названия родственных отношений: "родитель ", "брат " и т. д. Второй список должен быть пуст. Кроме этого, следует создать кнопку на форме familyForm, при нажатии на которую должно открываться это окно. После того, как в первом списке будет выделено название родственного отношения, во втором списке должен отображаться список соответствующих родственников выделенного (в окне familyForm) члена семьи.
5.2. Создайте окно для поиска в базе данных с помощью регулярных выражений (см. класс regEx). Регулярное выражение вводится в поле редактирования. Поиск ведется в строках вида "<имя> <фамилия> ". Результаты должны выводиться в списке.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.