Ruby/Desktop(Qt4)

Материал из Викиучебника

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

[править] Пример "простого тестового редактора", написанного на Ruby + Qt4.

Сейчас мы напишем простой текстовый редактор (просмотрщик для начала).

Нам понадобится ruby1.8 и rbuic4 в системе GNU/Linux. Причем при установке последнего должны будут установиться необходимые библиотеки по работе с Qt4 в ruby. Интерфейс будет делаться в Qt Designer (designer-qt4)


В Qt Designer создаем новую форму, основанную на "Main Window". На форму помещаем 2 кнопки типа "Push Button" и поле для редактирования текста - "Text Edit"

Для первой кнопки установим текст - "Открыть файл": через свойство "text" в окне Property Editor или по двойному клику на кнопке. Так же установим для неё ObjectName - "b_open": опять же через Property Editor или в контекстном меню выбрав Change objectName.

Для главной формы objectName я установил как - "notepad", а для Text Edit как "editor_window"

Для второй кнопки установим название "закрыть" и objectName - "b_close". Кнопка что должна делать? Правильно, закрывать окно. В Qt-Disigner'a в окне Signal/Slot Editor добавим новый слот: Sender -> b_close Signal -> clicked() Receive -> notepad Slot -> close()

И сохраняем проект как editor.ui

Теперь выполним команду:

$ rbuic4 editor.ui -x > editor.rb

для того, чтобы получить класс Ruby - Ui_Notepad.

Опция -x добавляет инструкции в файл для запуска приложения. Можно сейчас запустить форму, чтобы убедиться что всё работает:

$ ruby -Ku editor.rb

опции -Ku предназначены для коррекной обработки UTF-8.

Но тут есть одна тонкость - если мы будем вносить какие-то изменения в интерфейс - будет переписываться файл editor.rb. Поэтому мы создадим отдельный скрипт, который будет вызывать форму, назовем его start.rb. Перегенерируем форму: rbuic4 editor.ui > editor.rb, и напишем start.rb следующим образом:

require 'Qt4'
require 'editor.rb'
 
class StartQT4 < Qt::MainWindow
  def initialize parent=nil
    super
    @ui = Ui_Notepad.new
    @ui.setupUi self
  end
end
 
if $0 == __FILE__
    app = Qt::Application.new(ARGV)
    myapp = StartQT4.new
    myapp.show
    app.exec
end


Сейчас кнопка "закрыть" - работает. Пора настроить кнопку "открыть". Внесем изменения в start.rb

require 'Qt4'
require 'editor.rb'
 
class StartQT4 < Qt::MainWindow
  #перечисляем используемые слоты
  slots 'file_dialog()'
 
  def initialize parent=nil
    super
    @ui = Ui_Notepad.new
    @ui.setupUi self
    #тут мы обрабатываем сигнал
    Qt::Object.connect(@ui.b_open, SIGNAL('clicked()'), self, SLOT('file_dialog()'))
  end
 
  #метод, который выполняет при нажатии на кнопку.
  def file_dialog
    @ui.editor_window.setText 'wikibooks: Ruby'
  end
end
 
if $0 == __FILE__
    app = Qt::Application.new(ARGV)
    myapp = StartQT4.new
    myapp.show
    app.exec
end

Если запустить приложение - при нажатии на кнопку ('clicked()') вызывается слот 'file_dialog()', и в свою очередь вызывается метод file_dialog, который вставляет текст 'wikibooks: Ruby' в EditText'у.

Сейчас мы используем Qt::FileDialog для выбора файла. Следующий код:

require 'Qt4'
require 'editor.rb'
 
class StartQT4 < Qt::MainWindow
 
  slots 'file_dialog()'
 
  def initialize parent=nil
    super
    @ui = Ui_Notepad.new
    @ui.setupUi self
    Qt::Object.connect(@ui.b_open, SIGNAL('clicked()'), self, SLOT('file_dialog()'))
  end
 
  def file_dialog
    f = Qt::FileDialog
    text = File.new(f.getOpenFileName).read
    @ui.editor_window.setText text
  end
end
 
if $0 == __FILE__
    app = Qt::Application.new(ARGV)
    myapp = StartQT4.new
    myapp.show
    app.exec
end

f.getOpenFileName покажет диалог выбора файла, который закрывается после выбора файла (и возвращается путь к файлу), прерывая выполнения кода. Это работает, но если мы нажмем "отмена" при работе окна f.getOpenFileName мы не получим пути к файлу, но получим следущую ошибку: start.rb:17:in `initialize': can't convert nil into String (TypeError)

Т.е. если файл не выбран - возвращается nil. Следующий код включает проверку возвращаемого значения:

require 'Qt4'
require 'editor.rb'
 
class StartQT4 < Qt::MainWindow
 
  slots 'file_dialog()'
 
  def initialize parent=nil
    super
    @ui = Ui_Notepad.new
    @ui.setupUi self
    Qt::Object.connect(@ui.b_open, SIGNAL('clicked()'), self, SLOT('file_dialog()'))
  end
 
  def file_dialog
    f = Qt::FileDialog
    if @filename = f.getOpenFileName
      text = File.new(@filename).read
      @ui.editor_window.setText text
    end
  end
 
end
 
if $0 == __FILE__
    app = Qt::Application.new(ARGV)
    myapp = StartQT4.new
    myapp.show
    app.exec
end

Сейчас мы можем выбрать файл, но не можем сохранить его. Давайте добавим кнопку "сохранить" в QTDesign'e и назначем objectName - 'b_save', и перегенерируем GUI из нового ui-файла: rbuic4 editor.ui > editor.rb

Сейчас приложение выглядит следующим образом:

Мы добавим слот для сохранения файла и создадим коннект ему с сигналом "clicked()" на pushButton-кнопку "сохранить:

require 'Qt4'                                               
require 'editor.rb'
 
class StartQT4 < Qt::MainWindow
 
  slots 'file_dialog()', 'file_save()'
 
  def initialize parent=nil
    super
    @ui = Ui_Notepad.new
    @ui.setupUi self
    Qt::Object.connect(@ui.b_open, SIGNAL('clicked()'), self, SLOT('file_dialog()'))
    Qt::Object.connect(@ui.b_save, SIGNAL('clicked()'), self, SLOT('file_save()'))
  end
 
  def file_dialog
    f = Qt::FileDialog
    if @filename = f.getOpenFileName
      text = File.new(@filename).read
      @ui.editor_window.setText text
    end
  end
 
  def file_save
    if @filename
      f = File.new @filename, 'w'
      f.puts @ui.editor_window.toPlainText
      f.close
    end
  end
end
 
if $0 == __FILE__
    app = Qt::Application.new(ARGV)
    myapp = StartQT4.new
    myapp.show
    app.exec
end

И так мы получили приложение, которое открывает текстовые файлы и сохраняет изменения в этом файле.