您的位置:首页 > 编程语言 > Qt开发

Archlinux中利用QtDesigner进行Ruby编程

2013-08-28 18:07 295 查看
先附上一个Qt的文档吧,有什么不明白的在里面查就可以了:http://www.kuqin.com/qtdocument/classes.html

QtDesigner是Qt的一个窗体界面设计器。

我们首先要有一个QtDesigner,Qt的包里有。

然后要有qtbindings,可以用Ruby的"gem install qtbindings"来安装。
值得一提的是,qtbindings里面有个小程序rbuic4,这是将Designer生成的文件转换为rb文件的利器,过一会儿就能知道有多神奇了。

我们先创建几个文件夹:

$ mkdir ~/Project/phone_book     # 工程所在的文件夹
$ mkdir ~/Project/phone_book/ui  # 存放QtDesigner生成的文件


然后打开Designer,画出两个窗体:


上图:列表界面list.ui & 下图:编辑器editor.ui



有了Designer画起来是很方便的,别忘了给控件起名字!这里提一下我的命名书写方式,我喜欢用"控件类型简写"+"自定义名称",而且多个单词我喜欢用纯字母不加空格地列出来,然后将非首单词的每个单词首字母都大写,例如有个输入姓名用的LineEdit,我就起名为"txtName",有个方法是用来删除所有信息,我就起名为"clearAllContents",起名只是个人爱好而已,不必强求。

这是个简单的电话簿应用,你可以通过点击主界面上的“添加”或“编辑”按钮打开编辑器来添加或者编辑某个人的信息;“删除”按钮则用于删除某条信息;“清空”则是清空整个列表。

让我们在终端里ls一下看看:

$ ls ~/Project/phone_book
total 8
-rw-r--r-- 1 rex rex 2228 Aug 28 15:59 editor.ui
-rw-r--r-- 1 rex rex 2873 Aug 28 15:50 list.ui


嗯,应该是没什么问题了。

接下来要用到rbuic4这个强大的工具了,大概用法是这样的:

$ rbuic4 list.ui -x -o list.rb
$ rbuic4 editor.ui -x -o editor.rb


其中,选项-x表示生成可直接运行的Ruby代码,选项-o后面接输出文件名。

可能有的人找不到rbuic4在哪里,它藏在~/.gem/ruby/2.0.0/bin/里面。

我们将这两个生成的rb文件分别运行一下试试,效果跟之前的图片应该是一致的,除了没有了“[预览]”这个字样以外。

其实,Designer生成的ui文件本质上是xml,以我的“编辑器”editor.ui为例:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>frmEditor</class>
<widget class="QDialog" name="frmEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>105</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>400</width>
<height>105</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>400</width>
<height>105</height>
</size>
</property>
<property name="font">
<font>
<family>文泉驿微米黑</family>
</font>
</property>
<property name="windowTitle">
<string>Editor</string>
</property>
<widget class="QLabel" name="lblName">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>59</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>姓名:</string>
</property>
</widget>
<widget class="QLabel" name="lblNumber">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>59</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>电话:</string>
</property>
</widget>
<widget class="QLineEdit" name="txtName">
<property name="geometry">
<rect>
<x>50</x>
<y>10</y>
<width>341</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="txtNumber">
<property name="geometry">
<rect>
<x>50</x>
<y>40</y>
<width>341</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="btnYes">
<property name="geometry">
<rect>
<x>220</x>
<y>70</y>
<width>80</width>
<height>25</height>
</rect>
</property>
<property name="text">
<string>添加(&C)</string>
</property>
</widget>
<widget class="QPushButton" name="btnNo">
<property name="geometry">
<rect>
<x>310</x>
<y>70</y>
<width>80</width>
<height>25</height>
</rect>
</property>
<property name="text">
<string>取消(&X)</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>


然后看看rbuic4生成的对应的editor.rb文件:

=begin
** Form generated from reading ui file 'edit.ui'
**
** Created: Wed Aug 28 16:13:44 2013
**      by: Qt User Interface Compiler version 4.8.5
**
** WARNING! All changes made in this file will be lost when recompiling ui file!
=end

require 'Qt4'

class Ui_FrmEditor
attr_reader :lblName
attr_reader :lblNumber
attr_reader :txtName
attr_reader :txtNumber
attr_reader :btnYes
attr_reader :btnNo

def setupUi(frmEditor)
if frmEditor.objectName.nil?
frmEditor.objectName = "frmEditor"
end
frmEditor.resize(400, 105)
frmEditor.minimumSize = Qt::Size.new(400, 105)
frmEditor.maximumSize = Qt::Size.new(400, 105)
@font = Qt::Font.new
@font.family = "\346\226\207\346\263\211\351\251\277\345\276\256\347\261\263\351\273\221"
frmEditor.font = @font
@lblName = Qt::Label.new(frmEditor)
@lblName.objectName = "lblName"
@lblName.geometry = Qt::Rect.new(10, 10, 59, 21)
@lblNumber = Qt::Label.new(frmEditor)
@lblNumber.objectName = "lblNumber"
@lblNumber.geometry = Qt::Rect.new(10, 40, 59, 21)
@txtName = Qt::LineEdit.new(frmEditor)
@txtName.objectName = "txtName"
@txtName.geometry = Qt::Rect.new(50, 10, 341, 21)
@txtNumber = Qt::LineEdit.new(frmEditor)
@txtNumber.objectName = "txtNumber"
@txtNumber.geometry = Qt::Rect.new(50, 40, 341, 21)
@btnYes = Qt::PushButton.new(frmEditor)
@btnYes.objectName = "btnYes"
@btnYes.geometry = Qt::Rect.new(220, 70, 80, 25)
@btnNo = Qt::PushButton.new(frmEditor)
@btnNo.objectName = "btnNo"
@btnNo.geometry = Qt::Rect.new(310, 70, 80, 25)

retranslateUi(frmEditor)

Qt::MetaObject.connectSlotsByName(frmEditor)
end # setupUi

def setup_ui(frmEditor)
setupUi(frmEditor)
end

def retranslateUi(frmEditor)
frmEditor.windowTitle = Qt::Application.translate("frmEditor", "Editor", nil, Qt::Application::UnicodeUTF8)
@lblName.text = Qt::Application.translate("frmEditor", "\345\247\223\345\220\215\357\274\232", nil, Qt::Application::UnicodeUTF8)
@lblNumber.text = Qt::Application.translate("frmEditor", "\347\224\265\350\257\235\357\274\232", nil, Qt::Application::UnicodeUTF8)
@btnYes.text = Qt::Application.translate("frmEditor", "\346\267\273\345\212\240(&C)", nil, Qt::Application::UnicodeUTF8)
@btnNo.text = Qt::Application.translate("frmEditor", "\345\217\226\346\266\210(&X)", nil, Qt::Application::UnicodeUTF8)
end # retranslateUi

def retranslate_ui(frmEditor)
retranslateUi(frmEditor)
end

end

module Ui
class FrmEditor < Ui_FrmEditor
end
end  # module Ui

if $0 == __FILE__
a = Qt::Application.new(ARGV)
u = Ui_FrmEditor.new
w = Qt::Dialog.new
u.setupUi(w)
w.show
a.exec
end


注意到,有个setup_ui的方法其实是setupUi的另一种表述,看来这个工具还挺善解人意的。不过我可用不到,于是就都删掉了。

你可能会问,怎么rb文件中没有中文了呢?我才不告诉你那一堆右斜杠就是呢!

注意第77行~第84行,这就是刚才的选项-x加上的,正因如此你才能直接运行这个rb文件。如果不想直接运行的话可以不用-x或者把这几行删掉。为了不干扰后面的工作,我还是先删掉吧,毕竟让一个窗口能自己运行是很不好玩的。此外,Module那一块在我看来也是鸡肋,删掉无妨。

我们写一个主程序appMain.rb,内容如下:

require 'Qt4'
require './list'
require './editor'

if $0 == __FILE__
a = Qt::Application.new(ARGV)
u = Ui_FrmMain.new
w = Qt::Dialog.new
u.setupUi(w)
w.show
a.exec
end


用Ruby运行一下,效果已经很好了。但是有个最大的不足,就是按钮什么的都没反应,所以我们还得继续努力。

我们把主程序扩充一下:

require 'Qt4'
require './list'
require './editor'

class EditorForm < Qt::Dialog
slots 'insert()', 'edit()', 'cancel()'
attr_reader :ui
def initialize(parent, isAdd, name = "", number = "")
super(parent)
@ui = FrmEditor.new
@ui.setupUi(self)
@ui.txtName.setText(name)
@ui.txtNumber.setText(number)
if isAdd
Qt::Object.connect(@ui.btnYes, SIGNAL('clicked()'), self, SLOT('insert()'))
else
Qt::Object.connect(@ui.btnYes, SIGNAL('clicked()'), self, SLOT('edit()'))
end
Qt::Object.connect(@ui.btnNo, SIGNAL('clicked()'), self, SLOT('cancel()'))
self.show
end
def insert()
if @ui.txtName.text == ""
Qt::MessageBox.warning(self, "警告", "请输入名字!")
return
elsif @ui.txtNumber.text == ""
Qt::MessageBox.warning(self, "警告", "请输入号码!")
return
end
self.parent.ui.lstList.addItem(@ui.txtName.text + ": " + @ui.txtNumber.text)
self.dispose
end
def edit()
self.parent.ui.lstList.current_item.text = @ui.txtName.text + ": " + @ui.txtNumber.text
self.dispose
end
def cancel()
self.dispose
end
end

class MainForm < Qt::Dialog
slots 'addItem()', 'editItem()', 'deleteItem()'
attr_reader :ui
def initialize
super
@ui = FrmList.new
@ui.setupUi(self)
Qt::Object.connect(@ui.btnAdd, SIGNAL('clicked()'), self, SLOT('addItem()'))
Qt::Object.connect(@ui.btnEdit, SIGNAL('clicked()'), self, SLOT('editItem()'))
Qt::Object.connect(@ui.btnDelete, SIGNAL('clicked()'), self, SLOT('deleteItem()'))
Qt::Object.connect(@ui.btnClear, SIGNAL('clicked()'), @ui.lstList, SLOT('clear()'))
self.show
end
def addItem()
d = EditorForm.new(self, true)
end
def editItem()
if @ui.lstList.current_item # 如果选中了某一项
temp = @ui.lstList.current_item.text
a = temp.split(/: /)
d = EditorForm.new(self, false, a[0], a[1])
end
end
def deleteItem()
@ui.lstList.current_item.dispose if @ui.lstList.current_item
end
end

if $0 == __FILE__
a = Qt::Application.new(ARGV)
MainForm.new
a.exec
end


于是大功告成!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: