В предыдущем посту ( f3ex.habrahabr.ru/blog/54673 ) я писал, как при помощи ruby и Qt4 написать «простой текстовый редактор».
Продолжение портирования примеров из Python+Qt4 на Ruby+Qt4
Часть 2.
Теперь рассмотрим такой вопрос: когда не выбран файл или не сделано изменений в тексте — кнопка «сохранить» должна быть не активной.
За активность отвечает свойство «enabled» в Qt Disigner'e или это свойство можно установить из ruby-кода используя метод setEnabled
Установите для кнопки b_save свойство enabled в false (снимите галочку) и перегенерируйте форму editor.rb.
Чтобы узнать, что текст изменился, мы будем использовать сигнал textChanged() для textEdit.
Давай изменим код start.rb на следующий:
Что было добавлено. Мы добавили слот, который вызывается при изменении текста в textEdit и активирует кнопку:
В методе file_dialog, когда мы добавляем текст в textEdit из файла мы деактивирум кнопку:
Сейчас когда мы открываем файл — не сохраняются изменения в текущем открытом файле. Нужно сделать диалоговое окно (message box), которое будет спрашивать об изменених — «сохранить», «не сохранять» или «отменить». Для этих целей мы будем использовать MessageBox.
Вызов message box выглядит следующим образом
Нужно настроить это окно. Мы добавим кнопки и некоторый текст. Но как мы это сделаем? Нам нужно подредактировать метод file_dialog и если были произведены изменения — показать сообщение. Как мы узнаем были ли изменения? Если кнопка «сохранить» активна (@ui.b_save.idEnabled) — значит у нас есть несохраненные изменения. И так, внесем изменения:
Изменения внесены в строчки 18-46
Мы создаем новый экземпляр класса Qt::MessageBox, присваиваем текст сообщения (setText), заголовок окна setWindowTitle, иконку (setIcon), устанавливаем 3 кнопки («сохранить», «не сохранять» и «отменить»). Как второй аргумент устанавливаем типы кнопок (role). Информацию по этим типам можной найти в документации по QT. setDetailedText уставливает детальный вывод сообщения при нажатии на кнопку «show details». И в конце мы вызываем метод exec. message.clickedButton — возвращает объкст типа pushButton нажатой кнопки. Мы же в примере просто оперируем с текстом этой кнопки.
Диалоговое окно выглядит примерно так:
Исходные коды примером можно загрузить на странице:
Предыдущий пример: 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
Продолжение портирования примеров из Python+Qt4 на Ruby+Qt4
Часть 2.
Теперь рассмотрим такой вопрос: когда не выбран файл или не сделано изменений в тексте — кнопка «сохранить» должна быть не активной.
За активность отвечает свойство «enabled» в Qt Disigner'e или это свойство можно установить из ruby-кода используя метод setEnabled
Установите для кнопки b_save свойство enabled в false (снимите галочку) и перегенерируйте форму editor.rb.
Чтобы узнать, что текст изменился, мы будем использовать сигнал textChanged() для textEdit.
Давай изменим код start.rb на следующий:
Copy Source | Copy HTML
- require 'Qt4'
- require 'editor.rb'
-
- class StartQT4 < Qt::MainWindow
-
- slots 'file_dialog()', 'file_save()', 'enable_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()'))
- Qt::Object.connect(@ui.editor_window, SIGNAL('textChanged()'), self, SLOT('enable_save()'))
- end
-
- def file_dialog
- f = Qt::FileDialog
- if @filename = f.getOpenFileName
- text = File.new(@filename).read
- @ui.editor_window.setText text
- #Вставка текста в форму деактивирует кнопку и
- #начинает "слежку" за изменением текст textChanged()
- @ui.b_save.setEnabled false
- end
- end
-
- def enable_save
- @ui.b_save.setEnabled true
- 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
Что было добавлено. Мы добавили слот, который вызывается при изменении текста в textEdit и активирует кнопку:
Copy Source | Copy HTML
- Qt::Object.connect(@ui.editor_window, SIGNAL('textChanged()'), self, SLOT('enable_save()'))
Copy Source | Copy HTML
- def enable_save
- @ui.b_save.setEnabled true
- end
В методе file_dialog, когда мы добавляем текст в textEdit из файла мы деактивирум кнопку:
Copy Source | Copy HTML
- @ui.b_save.setEnabled false
Сейчас когда мы открываем файл — не сохраняются изменения в текущем открытом файле. Нужно сделать диалоговое окно (message box), которое будет спрашивать об изменених — «сохранить», «не сохранять» или «отменить». Для этих целей мы будем использовать MessageBox.
Вызов message box выглядит следующим образом
Copy Source | Copy HTML
- message = Qt::MessageBox.new
- message.exec
Нужно настроить это окно. Мы добавим кнопки и некоторый текст. Но как мы это сделаем? Нам нужно подредактировать метод file_dialog и если были произведены изменения — показать сообщение. Как мы узнаем были ли изменения? Если кнопка «сохранить» активна (@ui.b_save.idEnabled) — значит у нас есть несохраненные изменения. И так, внесем изменения:
Copy Source | Copy HTML
- require 'Qt4'
- require 'editor.rb'
-
- class StartQT4 < Qt::MainWindow
-
- slots 'file_dialog()', 'file_save()', 'enable_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()'))
- Qt::Object.connect(@ui.editor_window, SIGNAL('textChanged()'), self, SLOT('enable_save()'))
- end
-
- def file_dialog
- response = false
- # Текст кнопок:
- save = 'Сохранить'
- discard = 'Не сохранять'
- cancel = 'Отменить'
- #Если были изменения вызываем message_box
- if @ui.b_save.isEnabled && @filename
- message = Qt::MessageBox.new
- message.setText 'Что следует сделать с несохраненными изменениями ?'
- message.setWindowTitle('Блокнот')
- message.setIcon(Qt::MessageBox.Question)
- message.addButton(save,Qt::MessageBox.AcceptRole)
- message.addButton(discard,Qt::MessageBox.DestructiveRole)
- message.addButton(cancel,Qt::MessageBox.RejectRole)
- message.setDetailedText('Несохраненные изменения в файле: ' + @filename.to_s)
- message.exec
- response = message.clickedButton.text
- #Сохраняем файл
- if response == save
- file_save
- @ui.b_save.setEnabled false
- end
- #Не сохранять
- if response == discard
- @ui.b_save.setEnabled false
- end
- end
- #Если мы не хотим сохранять изменения
- unless response == cancel
- f = Qt::FileDialog
- if @filename = f.getOpenFileName
- text = File.new(@filename).read
- @ui.editor_window.setText text
- @ui.b_save.setEnabled false
- end
- end
- end
-
- def enable_save
- @ui.b_save.setEnabled true
- 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
Изменения внесены в строчки 18-46
Мы создаем новый экземпляр класса Qt::MessageBox, присваиваем текст сообщения (setText), заголовок окна setWindowTitle, иконку (setIcon), устанавливаем 3 кнопки («сохранить», «не сохранять» и «отменить»). Как второй аргумент устанавливаем типы кнопок (role). Информацию по этим типам можной найти в документации по QT. setDetailedText уставливает детальный вывод сообщения при нажатии на кнопку «show details». И в конце мы вызываем метод exec. message.clickedButton — возвращает объкст типа pushButton нажатой кнопки. Мы же в примере просто оперируем с текстом этой кнопки.
Диалоговое окно выглядит примерно так:
Исходные коды примером можно загрузить на странице:
Предыдущий пример: 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