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
И так мы получили приложение, которое открывает текстовые файлы и сохраняет изменения в этом файле.