📜 ⬆️ ⬇️

Ruby QT4 - text editor, part 1

Prelude.
Some time ago it was necessary to write a GUI to the parser with Yandex dictionaries (translation). What is b? Ruby, of course. I thought then. But how surprised I was when I practically did not find Russian documentation and examples to get acquainted with GUI programming. Yes, and the English-speaking did not really help: all some short scraps and notes like hello_worlds. This refers to Qt. The Qt Disigner site still has a Qt3 example. I had to write GUI on GTK +, and it was overwhelmed - the documentation on the module website is incomplete, unfinished, without examples ...

Recently it took to write GUI-applications. But by this time, having become acquainted with the basis of Python, I decided to see how it relates to the GUI. And in particular, Qt4, because I'm a kederaast :), and Qt4 is already replacing Qt3. In any case on my desktop. And I was pleasantly surprised - there are a lot of examples for Python, documentation, incl. and in Russian for this part. And I stumbled upon building good examples for Python + QT4 on the page: www.rkblog.rk.edu.pl/w/p/python - for example - writing a text editor from scratch. Where everything is detailed in the examples everything is taken apart. He sat 2 pm, figured out the basis, and wrote his own program.
And then I sit and think everything is good in the example, and Python is almost the same Ruby. We need to do a thing, rewrite the examples in Russian and under Ruby. What actually do now.

And so, let's go.
A simple test editor. Part 1

Now we will write a simple text editor (viewer to begin with).
')
We will need ruby1.8 and rbuic4. Moreover, when installing the latter, the necessary libraries for working with Qt4 in ruby ​​will be installed.
The interface will be made in Qt Designer (designer-qt4)

In Qt Designer, we create a new form based on the “Main Window”.
On the form we place 2 buttons like “Push Button” and the text editing field - “Text Edit”
image

For the first button, set the text - “Open file”: through the “text” property in the Property Editor window or by double clicking on the button.
Also set the ObjectName for it - “b_open”: again through the Property Editor or by selecting Change objectName in the context menu.

For the main form objectName, I set it as “notepad”, and for Text Edit as “editor_window”

For the second button, set the name “close” and objectName - “b_close”. What should the button do? Right, close the window. In QT-Disigner, in the Signal / Slot Editor window, add a new slot:
Sender -> b_close
Signal -> clicked ()
Receive -> notepad
Slot -> close ()

And save the project as editor.ui

Now run the command:
rbuic4 editor.ui -x> editor.rb

in order to get the Ruby class - Ui_Notepad.

The -x option adds instructions to the file to run the application. You can now run the form to make sure everything works:
ruby -Ku editor.rb

The -Ku options are intended for correct processing of UTF-8.

But there is one subtlety - if we make any changes to the interface - the editor.rb file will be overwritten. Therefore, we will create a separate script that will call the form, let's call it start.rb.
Re-generate the form: rbuic4 editor.ui> editor.rb, and write start.rb as follows:

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


Now the "close" button works. It's time to set up the "open" button.
Make changes to 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
# , .
# here we connect signals with our slots
Qt::Object.connect(@ui.b_open, SIGNAL('clicked()'), self, SLOT('file_dialog()'))
end

#, .
def file_dialog
@ui.editor_window.setText 'aaaaaaa'
end

end

if $0 == __FILE__
app = Qt::Application.new(ARGV)
myapp = StartQT4.new
myapp.show
app.exec
end

If you start the application, when you click on the button ('clicked ()'), the 'file_dialog ()' slot is called, and the file_dialog method is called in turn, which inserts the text 'aaaaaaaa' into EditText.

Now we use Qt :: FileDialog to select a file. The following code:
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 will show the file selection dialog, which closes after the file is selected (and the file path returns), interrupting code execution. This works, but if we click "cancel" while the f.getOpenFileName window is working, we will not get the path to the file, but we will get the following error:
start.rb: 17: in `initialize ': can't convert nil into String (TypeError)

image

Those. if no file is selected, returns nil. The following code includes a check for the return value:
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


Now we can select a file, but we can not save it. Let's add the “save” button in QTDesign and assign objectName - 'b_save', and re-generate the GUI from the new ui-file:
rbuic4 editor.ui > editor.rb

Now the application looks like this:
image

We will add a slot to save the file and create a connection with the “clicked ()” signal on the pushButton-button “save:
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


image

And so we got an application that opens text files and saves changes to this file.
The following article will expand the capabilities of the application.

I ran the application on Ubuntu 8.10, there were no problems with the encoding, and we don’t forget about the ruby ​​-Ku keys to support UTF-8.

ZY Forgive the formatting of the code, the first time I write a post. Like the tags <code> </ code>, and everything moved to the left. I would be grateful if you tell me how to make out the code.
ZZY I still have a bad understanding of Qt terminology. I would also be happy if you comment on what a "connection", "slot" is

Source: https://habr.com/ru/post/54673/


All Articles