Search
Write a publication
Pull to refresh

Qt + Ruby, пример рисования 2D

Reading time5 min
Views869
Qt + Ruby, пример рисования 2D.

Предусловие

Читая хабр я несколько раз слышал о 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 Window
require '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.
Tags:
Hubs:
Total votes 5: ↑2 and ↓3-1
Comments2

Articles