Приветствую Вас, Гость
Главная » Статьи » Мои статьи

Пример работы с Qt

Основной алгоритм прост. Он укладывается в следующую схему:

  1. Г рузим в память QtGui и QtCore (это основные файлы Qt)
  2. Ищем в них нужные функции и помещаем их в таблицу
  3. Пишем своё небольшое дерево классов, которое будет вызывать внешние функции из Qt, пользуясь нашей таблицей.
  4. Всё, что не удастся вызвать напрямую из  QtGui и QtCore, обернём в C функции в QtE.dll, маленькой dll, призванной обойти то, что сделать напрямую не удаётся. 
Итак, после нескольких экспериментов, стало понятно, что справится напрямую с конструкторами и деструкторами Qt, мне не по силам. Программы разваливались из за конфликтов памяти. Тогда, я решил, что QtE будет создавать экземпляры классов Qt и отдавать их мне в D.
Единственный объект, который создается реальным конструктором C++ непосредственно в D, это QApplication. Это позволило сохранить привычный вид программы, без использования сложного обратного вызова, как мне пришлось делать в Forth.

Следующий, хитрый момент, это события. В Qt основной механизм Слоты-Сигналы. Это отлично, но там есть и обычный подход к обработке событий, а именно виртуальные функции вызываемые в ответ на событие. Вот QtE и занимается тем, что добавляет   в классы Qt поля (свойства) хранящие адреса функций обратных вызовов функций D, а так же перекрывает необходимые виртуальные функции. Таким образом, и в QtE минимум C++ кода, и в D его не много, только то, что нужно.

Немного попрактиковавшись, добавить нужный класс или метод класса можно довольно быстро. 

Пример:

import qte; // Работа с Qt 
import core.runtime;
import std.stdio;

// Это наш обработчик события изменения размера окна
void resize(void* qq) {
writeln("!");
}

// Это наш слот, вернее обработчик события вызова слота
void Кнопка1() {
gWidget w10 = new gWidget(null, 0);
w10.setWindowTitle(new QString("Это окно из моего слота!!!!"w));
w10.resize(500, 150);
w10.show();
}

int main(string[] args) {
// Цепляем библиотеки QtCore, QtGui, QtE.
int rez = LoadQt(); if (rez==1) return 1; // Ошибка загрузки библиотеки


QApplication app = new QApplication; // Создали, но конструктор не вызван
// Изврат связанный с тем, что вызов конструктора QApplication
// должен быть произведен в main(), иначе в Linux ошибка ....

(app.adrQApplication())(cast(void*)app.bufObj, &Runtime.cArgs.argc, Runtime.cArgs.argv);

// Создаём окно
gWidget w1 = new gWidget(null, 0);
w1.setResizeEvent(&resize); // Установить обработчик на resize


w1.resize(300, 100); w1.show();
wstring ss = "Привет!"w;
wstring ss2 = ss ~ " - ура!"w;
QString qs2 = new QString(ss2);

gWidget w2 = new gWidget(null, 0); w2.resize(400, 50); w2.show();
w2.setWindowTitle(new QString("Ещё одно окошко!"w));

QTextEdit textEd7 = new QTextEdit(null);
textEd7.append(new QString("Это textEd7 ... При изменении текста вызов сигнала textChanged() с привязкой к aboutQt()"));
textEd7.setWindowTitle(qs2);
textEd7.show();

QByteArray ba = new QByteArray();
w1.setWindowTitle(qs2);


gPushButton копка1 = new gPushButton(null, qs2);

// Пример привязки стандартного сигнала к стандартному слоту
textEd7.connect(textEd7.QtObj(), MSS("textChanged()", QSIGNAL), app.QtObj(), MSS("aboutQt()", QSLOT), 1);
// мы так же можем сделать свой СОБСТВЕННЫЙ СЛОТ!!! Для этого будем использовать
// объект slot замечательного класса gSlot.

gSlot slot0 = new gSlot(); slot0.setSlot0(&Кнопка1); // Установить обработчик на Кнопку
// Вяжем стандартный сигнал на наш слот
копка1.connect(копка1.QtObj(), MSS("clicked()", QSIGNAL), slot0.QtObj(), MSS("Slot0()", QSLOT), 1);
// Вяжем наш сигнал с стандартным слотом aboutQt
копка1.connect(slot0.QtObj(), MSS("Signal0()", QSIGNAL), app.QtObj(), MSS("aboutQt()", QSLOT), 1);
// Инициируем наш сигнал
slot0.emitSignal0();

копка1.show();
return app.exec();
}

Категория: Мои статьи | Добавил: mgw (12.08.2013) | Автор: Мохов Геннадий Владимирович E W
Просмотров: 1005 | Теги: qt, forth, D lang | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email *:
Код *: