Как стать автором
Обновить

Ruby + Qt4, простой текстовый редактор, ч. 2

Время на прочтение7 мин
Количество просмотров534
В предыдущем посту ( f3ex.habrahabr.ru/blog/54673 ) я писал, как при помощи ruby и Qt4 написать «простой текстовый редактор».
Продолжение портирования примеров из Python+Qt4 на Ruby+Qt4

Часть 2.

Теперь рассмотрим такой вопрос: когда не выбран файл или не сделано изменений в тексте — кнопка «сохранить» должна быть не активной.
За активность отвечает свойство «enabled» в Qt Disigner'e или это свойство можно установить из ruby-кода используя метод setEnabled
Установите для кнопки b_save свойство enabled в false (снимите галочку) и перегенерируйте форму editor.rb.

image



Чтобы узнать, что текст изменился, мы будем использовать сигнал textChanged() для textEdit.

Давай изменим код start.rb на следующий:

Copy Source | Copy HTML
  1. require 'Qt4'
  2. require 'editor.rb'
  3.  
  4. class StartQT4 < Qt::MainWindow
  5.  
  6.   slots 'file_dialog()', 'file_save()', 'enable_save()'
  7.  
  8.   def initialize parent=nil
  9.     super
  10.     @ui = Ui_Notepad.new
  11.     @ui.setupUi self
  12.     Qt::Object.connect(@ui.b_open, SIGNAL('clicked()'), self, SLOT('file_dialog()'))
  13.     Qt::Object.connect(@ui.b_save, SIGNAL('clicked()'), self, SLOT('file_save()'))
  14.     Qt::Object.connect(@ui.editor_window, SIGNAL('textChanged()'), self, SLOT('enable_save()'))
  15.   end
  16.  
  17.   def file_dialog
  18.     f = Qt::FileDialog
  19.     if @filename = f.getOpenFileName
  20.       text = File.new(@filename).read
  21.       @ui.editor_window.setText text
  22.       #Вставка текста в форму деактивирует кнопку и
  23.       #начинает "слежку" за изменением текст textChanged()
  24.       @ui.b_save.setEnabled false
  25.     end
  26.   end
  27.  
  28.   def enable_save
  29.     @ui.b_save.setEnabled true
  30.   end
  31.  
  32.   def file_save
  33.     if @filename
  34.       f = File.new @filename, 'w'
  35.       f.puts @ui.editor_window.toPlainText
  36.       f.close
  37.     end
  38.   end
  39. end
  40.  
  41. if $0 == __FILE__
  42.     app = Qt::Application.new(ARGV)
  43.     myapp = StartQT4.new
  44.     myapp.show
  45.     app.exec
  46. end


Что было добавлено. Мы добавили слот, который вызывается при изменении текста в textEdit и активирует кнопку:
Copy Source | Copy HTML
  1. Qt::Object.connect(@ui.editor_window, SIGNAL('textChanged()'), self, SLOT('enable_save()'))


Copy Source | Copy HTML
  1. def enable_save
  2.   @ui.b_save.setEnabled true
  3. end


В методе file_dialog, когда мы добавляем текст в textEdit из файла мы деактивирум кнопку:
Copy Source | Copy HTML
  1. @ui.b_save.setEnabled false


Сейчас когда мы открываем файл — не сохраняются изменения в текущем открытом файле. Нужно сделать диалоговое окно (message box), которое будет спрашивать об изменених — «сохранить», «не сохранять» или «отменить». Для этих целей мы будем использовать MessageBox.

Вызов message box выглядит следующим образом
Copy Source | Copy HTML
  1. message = Qt::MessageBox.new
  2. message.exec


image

Нужно настроить это окно. Мы добавим кнопки и некоторый текст. Но как мы это сделаем? Нам нужно подредактировать метод file_dialog и если были произведены изменения — показать сообщение. Как мы узнаем были ли изменения? Если кнопка «сохранить» активна (@ui.b_save.idEnabled) — значит у нас есть несохраненные изменения. И так, внесем изменения:

Copy Source | Copy HTML
  1. require 'Qt4'
  2. require 'editor.rb'
  3.  
  4. class StartQT4 < Qt::MainWindow
  5.  
  6.   slots 'file_dialog()', 'file_save()', 'enable_save()'
  7.  
  8.   def initialize parent=nil
  9.     super
  10.     @ui = Ui_Notepad.new
  11.     @ui.setupUi self
  12.     Qt::Object.connect(@ui.b_open, SIGNAL('clicked()'), self, SLOT('file_dialog()'))
  13.     Qt::Object.connect(@ui.b_save, SIGNAL('clicked()'), self, SLOT('file_save()'))
  14.     Qt::Object.connect(@ui.editor_window, SIGNAL('textChanged()'), self, SLOT('enable_save()'))
  15.   end
  16.  
  17.   def file_dialog
  18.     response = false
  19.     # Текст кнопок:                                                                            
  20.     save = 'Сохранить'
  21.     discard = 'Не сохранять'
  22.     cancel = 'Отменить'
  23.     #Если были изменения вызываем message_box                                                  
  24.     if @ui.b_save.isEnabled && @filename
  25.       message = Qt::MessageBox.new
  26.       message.setText 'Что следует сделать с несохраненными изменениями ?'
  27.       message.setWindowTitle('Блокнот')
  28.       message.setIcon(Qt::MessageBox.Question)
  29.       message.addButton(save,Qt::MessageBox.AcceptRole)
  30.       message.addButton(discard,Qt::MessageBox.DestructiveRole)
  31.       message.addButton(cancel,Qt::MessageBox.RejectRole)
  32.       message.setDetailedText('Несохраненные изменения в файле: ' + @filename.to_s)
  33.       message.exec
  34.       response = message.clickedButton.text
  35.       #Сохраняем файл                                                                          
  36.       if response == save
  37.         file_save
  38.         @ui.b_save.setEnabled false
  39.       end
  40.       #Не сохранять
  41.       if response == discard
  42.         @ui.b_save.setEnabled false
  43.       end
  44.     end
  45.     #Если мы не хотим сохранять изменения
  46.     unless response == cancel
  47.       f = Qt::FileDialog
  48.       if @filename = f.getOpenFileName
  49.         text = File.new(@filename).read
  50.         @ui.editor_window.setText text
  51.         @ui.b_save.setEnabled false
  52.       end
  53.     end
  54.   end
  55.  
  56.   def enable_save
  57.     @ui.b_save.setEnabled true
  58.   end
  59.  
  60.   def file_save
  61.     if @filename
  62.       f = File.new @filename, 'w'
  63.       f.puts @ui.editor_window.toPlainText
  64.       f.close
  65.     end
  66.   end
  67. end
  68.  
  69. if $0 == __FILE__
  70.     app = Qt::Application.new(ARGV)
  71.     myapp = StartQT4.new
  72.     myapp.show
  73.     app.exec
  74. end


Изменения внесены в строчки 18-46

Мы создаем новый экземпляр класса Qt::MessageBox, присваиваем текст сообщения (setText), заголовок окна setWindowTitle, иконку (setIcon), устанавливаем 3 кнопки («сохранить», «не сохранять» и «отменить»). Как второй аргумент устанавливаем типы кнопок (role). Информацию по этим типам можной найти в документации по QT. setDetailedText уставливает детальный вывод сообщения при нажатии на кнопку «show details». И в конце мы вызываем метод exec. message.clickedButton — возвращает объкст типа pushButton нажатой кнопки. Мы же в примере просто оперируем с текстом этой кнопки.
Диалоговое окно выглядит примерно так:

image

Исходные коды примером можно загрузить на странице:
Предыдущий пример: narod.ru/disk/6746280000/ruby_qt_simple_editor_1.zip.html
Текущий пример: narod.ru/disk/6746302000/ruby_qt_simple_editor_2.zip.html

Портирование на ruby следующего примера: www.rkblog.rk.edu.pl/w/p/extending-pyqt4-text-editor
Теги:
Хабы:
Всего голосов 19: ↑17 и ↓2+15
Комментарии1

Публикации

Истории

Ближайшие события