Qt + Ruby, пример рисования 2D.
Предусловие
Читая хабр я несколько раз слышал о Qt, но что это такое я, конечно же, не знал. И вот в один свободный денек почитываю хабр я снова натыкаюсь на Qt. Это, наверное, было последней каплей. Я решил узнать что же это за зверь такой и с чем его все-таки едят. Я направился как обычно на Википедию. Узнав не много о Qt я заинтересовался и начал бороздить просторы интернета все больше и больше углубляясь в данную тему. Затем прочитав на хабре вот эту статью. Википедию я, наконец, все настроил, а так же создал и запустил тестовое приложение. Я решил пойти дальше скачал последний QtCreator я начал разбираться в нем пока, в конце концов, не добрался до примера «2D Painting Example». Дело в том что данный пример был на С++ а мне хотелось на ruby. И тут я решил перевести весь этот пример на ruby. И у меня это получилось и даже заработало. Поэтому я решил выложить результат моей не долгой работы здесь может быть кому-то и пригодится.
Собственно реализация.
и собственно файл main.rb
Предусловие
Читая хабр я несколько раз слышал о Qt, но что это такое я, конечно же, не знал. И вот в один свободный денек почитываю хабр я снова натыкаюсь на Qt. Это, наверное, было последней каплей. Я решил узнать что же это за зверь такой и с чем его все-таки едят. Я направился как обычно на Википедию. Узнав не много о Qt я заинтересовался и начал бороздить просторы интернета все больше и больше углубляясь в данную тему. Затем прочитав на хабре вот эту статью. Википедию я, наконец, все настроил, а так же создал и запустил тестовое приложение. Я решил пойти дальше скачал последний QtCreator я начал разбираться в нем пока, в конце концов, не добрался до примера «2D Painting Example». Дело в том что данный пример был на С++ а мне хотелось на ruby. И тут я решил перевести весь этот пример на ruby. И у меня это получилось и даже заработало. Поэтому я решил выложить результат моей не долгой работы здесь может быть кому-то и пригодится.
Собственно реализация.
Class Helper
require 'Qt4'
# класс который используется для отрисовывания изображения
class Helper
@background;
@circleBrush;
@textFont;
@circlePen;
@textPen;
# конструктор
def initialize
gradient = Qt::LinearGradient.new(Qt::PointF.new(50, -20), Qt::PointF.new(80, 20))
@background = Qt::Brush.new(Qt::Color.new(64, 32, 64))
@circleBrush = Qt::Brush.new(gradient)
@circlePen = Qt::Pen.new(Qt::black);
@circlePen.setWidth(1);
@textPen = Qt::Pen.new(Qt::white);
@textFont = Qt::Font.new
@textFont.setPixelSize(50);
end
# метод, выполняющий не посредственно рисование
def paint(painter, event, elapsed)
painter.fillRect(event.rect(), @background)
painter.translate(100, 100)
painter.save();
painter.setBrush(@circleBrush);
painter.setPen(@circlePen);
painter.rotate(elapsed * 0.030);
r = elapsed/1000.0;
n = 30;
i = 0
while i < n do
i += 1
painter.rotate(30);
radius = 0 + 120.0*((i+r)/n)
circle_radius = 1 + ((i+r)/n)*20;
painter.drawEllipse(Qt::RectF.new(radius, -circle_radius, circle_radius*2, circle_radius*2))
end
painter.restore();
painter.setPen(@textPen);
painter.setFont(@textFont);
painter.drawText(Qt::Rect.new(-50, -50, 100, 100), Qt::AlignCenter, "Qt");
end
end
* This source code was highlighted with Source Code Highlighter.
Class Widget
require 'Qt4'
# класс widget окно для отображения нативной анимации
# наследник от Qt::Widget
class Widget < Qt::Widget
# поля класса
# используется для рисования
@helper;
# числовое значение будет использовано для поворота эллипсов
# для создания эффекта анимации
@elapsed;
# конструктор
def initialize(helper)
# вызовем конструктор предка
super()
# заполняем поля
@helper = helper
@elapsed = 0;
# установим размер окна
setFixedSize(200, 200);
end
# обозначим слот animate()
slots 'animate()'
# реализации слота animate()
def animate()
@elapsed = @elapsed + sender().interval() % 1000;
repaint();
end
# override метода paintEvent родительского класса
# который вызывается методом repaint()
def paintEvent(event)
# Создаем объект класса Qt::Painter
painter = Qt::Painter.new
# начинаем отрисовывать изображение
painter.begin(self);
painter.setRenderHint(Qt::Painter::Antialiasing);
# вызываем метод paint класса Helper для отрисовки изображения
@helper.paint(painter, event, @elapsed);
# заканчиваем отрисовку
painter.end();
end
end
* This source code was highlighted with Source Code Highlighter.
Class GlWidget
require 'Qt4'
# класс GLWidget окно отображения анимации с использованием OpenGL
# наследник от Qt::GLWidget
class GLWidget < Qt::GLWidget
# поля класса
# используется для рисования
@helper;
# числовое значение будет использовано для поворота эллипсов
# для создания эффекта анимации
@elapsed;
# конструктор
def initialize(helper, parent)
# вызовем конструктор предка
super(Qt::GLFormat.new(Qt::GL::SampleBuffers), parent)
# заполняем поля
@helper = helper
@elapsed = 0;
# установим размер окна
setFixedSize(200, 200);
setAutoFillBackground(false);
end
# обозначим слот animate()
slots 'animate()'
# реализации слота animate()
def animate()
@elapsed = @elapsed + sender().interval() % 1000;
repaint();
end
# override метода paintEvent родительского класса
# который вызывается методом repaint()
def paintEvent(event);
# Создаем объект класса Qt::Painter
painter = Qt::Painter.new
# начинаем отрисовывать изображение
painter.begin(self);
painter.setRenderHint(Qt::Painter::Antialiasing);
# вызываем метод paint класса Helper для отрисовки изображения
@helper.paint(painter, event, @elapsed);
# Заканчиваем отрисовку
painter.end();
end
end
* This source code was highlighted with Source Code Highlighter.
Class Windowrequire 'Widget'
require 'g_l_widget'
require 'Qt4'
# класс window окно для отображения всех раннее созданных widet'ов
# наследник от Qt::Widget
class Window < Qt::Widget
# поля класса
# используется для рисования
@helper
# конструктор
def initialize(helper)
# вызовем конструктор предка
super()
# заполним поля
@helper = helper
# формирование элементов отображение widget'a
native = Widget.new(@helper);
open_g_l = GLWidget.new(@helper, self);
native_label = Qt::Label.new(tr("Native"));
native_label.setAlignment(Qt::AlignHCenter);
open_g_l_label = Qt::Label.new("OpenGL");
open_g_l_label.setAlignment(Qt::AlignHCenter);
layout = Qt::GridLayout.new;
layout.addWidget(native, 0, 0);
layout.addWidget(open_g_l, 0, 1);
layout.addWidget(native_label, 1, 0);
layout.addWidget(open_g_l_label, 1, 1);
setLayout(layout);
# создадим объект таймер
timer = Qt::Timer.new(self);
# присоединим сигнал timeout() к слоту animate()
# для отрисовывания анимации по истечению таймера
connect(timer, SIGNAL('timeout()'), native, SLOT('animate()'));
connect(timer, SIGNAL('timeout()'), open_g_l, SLOT('animate()'));
# запускаем таймер
timer.start(50);
setWindowTitle("2D Painting on Native and OpenGL Widgets");
end
end
* This source code was highlighted with Source Code Highlighter.
и собственно файл main.rb
require 'helper'
require 'window'
require 'Qt4'
# создадим приложение Qt
app = Qt::Application.new(ARGV)
# экземпляр класса Helper для отрисовки изображения
helper = Helper.new
# окно для отображения всех widget'ов
widget = Window.new(helper)
# покажем окно
widget.show
# запустим приложение
app.exec
* This source code was highlighted with Source Code Highlighter.