这一段QT & 自定义widget

来源:互联网 发布:淘宝卖家微信交流群 编辑:程序博客网 时间:2024/05/21 14:58

       这几个月在用Qt做Linux下应用的界面,干的事情是什么呢? 主要是看在线文档,查api,堆砌代码。。。 没有太多技术含量,却也不容易做好,因为只查文档,不知道查哪个api,名字是什么? 这就要google了;整个流程是 : 需求-google-api名-doc-copy例子过来改改。

       发现几个问题:

 1 google不是万能的,不能搞定所以需求

 2 没有系统的知识体系,只有碎片、碎片、碎片——还没掌握好就急忙用,用一次就扔掉

 3 拼凑api有时不照,拼得不专业

 4 兴趣与耐心被磨灭, 不怎么动脑子, boss怎么说则么做,机器人。。。

 5 浮躁,总想一下子做出很多东西,却不愿意去看书,去了解清楚底层的基础,妄想在浮沙上筑高楼!

 

tips:
应该读书。 把知识体系和索引在脑子里建立起来,便于设计和查找,不确定的时候要去细细的查看和学习

虽然,上头老是急功近利地催促,自己还是要考虑学到东西没?

很ft的是,被上头影响得自己也越来越浮躁,不求甚解,只管表明混过去——有时自己都不耻自己了

 

 

custom widget的初体验

(FC8 2.6.23内核, QT4.4.3  Eclipse-qt-integration1.4.3 )

  这两天在看Vidalia的代码,关于VClickLabel,是个自定义控件,发现人家的ui文件中可以直接对text和pixmap属性进行编辑;而我把vclicklabel类放到工程中,并将widget promote成vclicklabel,发现没法编辑这两个属性,即使在Qt Designer中自己增加了这两个属性,仍然无法显示图像和文字。

  于是,研究下自定义控件,看到文章

  要想在Qt Designer中使用自定义控件,必须要使Qt Designer能够知道我们的自定义控件的存在。有两种方法可以把新自定义控件的信息通知给Qt Designer:“升级(promotion)”法和插件法
升级法最为简便快捷。顾名思义,升级法就是把Qt自有的控件进行升级改造一番。选一个Qt自有的控件,如果它和我们新加的自定义控件有着相似的API,那么只要在Qt Designer的对话框里面完成有关新控件的信息就一切大吉,新控件就可以用在QtDesigner创建的form中。但是在编辑和预览时,还是和Qt自有控件表示没有什么两样。
现在把HexSpinBox控件用升级方法插入到一个form中:
1.         用Qt Designer创建一个新的窗体,把控件箱里的QSpinBox添加到窗体中。
2.         右击spin box,选择“Promote to Custom Widget”上下文菜单。
3.         在弹出的对话框中,类名处填写“HexSpinBox”,头文件填写“hexspinbox.h”
好了。在uic生成的代码中包含有“hexspinbox.h”头文件而不是<QSpinBox>,还包含了一个HexSpinBox的实例,而不是QSpinBox。在Qt Designer中,HexSpinBox控件由QSpinBox表示,并且可以设置所有的QSpinBox的属性(如范围、当前值)。
Figure 5.6. Qt Designer's custom widget dialog
  
升级法的缺点是不能在Qt Designer中设置自定义控件自己的特有属性,也不能够绘制自己。这些问题可以用插件法解决。
插件法需要创建一个插件库,使Qt Designer能够实时加载,用来创建控件的实例。这样,QtDesigner就可以在编辑窗体或者预览的时候使用自定义控件。因为有了Qt的meta-object系统,QtDesigner能动态获得自定义控件的全部属性。现在以IconEditor为例,用插件法把IconEditor集成到Qt Designer中。
首先,我们从QDesignerCustomWidgetInterface派生一个新类,重写一些虚函数。我们假定这个插件的源代码在iconeditorplugin目录中,IconEditor类的代码在与它平行的目录iconeditor中。
这里是插件类的定义:
#include <QDesignerCustomWidgetInterface>
class IconEditorPlugin : public QObject, public QDesignerCustomWidgetInterface
{
    Q_OBJECT
    Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
    IconEditorPlugin(QObject *parent = 0);
    QString name() const;
    QString includeFile() const;
    QString group() const;
    QIcon icon() const;
    QString toolTip() const;
    QString whatsThis() const;
    bool isContainer() const;
    QWidget *createWidget(QWidget *parent);
};
 
IconEditorPlugin类是一个封装了IconEditor控件的工厂类,它使用了双继承,父类为QObject和QDesignerCustomWidgetInterface。宏Q_INTERFACES()告诉moc第二个基类为一个插件接口类。QtDesigner使用该类中的函数创建IconEditor的实例并得到有关它的信息。
源文件如下:
IconEditorPlugin::IconEditorPlugin(QObject *parent)
    : QObject(parent)
{
}
QString IconEditorPlugin::name() const
{
    return "IconEditor";
}
QString IconEditorPlugin::includeFile() const
{
    return "iconeditor.h";
}
QString IconEditorPlugin::group() const
{
    return tr("Image Manipulation Widgets");
}
QIcon IconEditorPlugin::icon() const
{
    return QIcon(":/images/iconeditor.png");
}
QString IconEditorPlugin::toolTip() const
{
    return tr("An icon editor widget");
}
QString IconEditorPlugin::whatsThis() const
{
    return tr("This widget is presented in Chapter 5 of <i>C++ GUI "
              "Programming with Qt 4</i> as an example of a custom Qt "
              "widget.");
}
bool IconEditorPlugin::isContainer() const
{
    return false;
}
QWidget *IconEditorPlugin::createWidget(QWidget *parent)
{
    return new IconEditor(parent);

Q_EXPORT_PLUGIN2(iconeditorplugin, IconEditorPlugin)
 
构造函数是一个空函数。
函数name()返回插件提供的控件的名称。
函数includeFile()得到插件封装的特定控件的头文件,这个头文件包含在uic工具产生的代码中。
函数group()返回的是该自定义控件所属的工具箱(box group)的名字。如果Qt Designer中没有这个名字,就会为这个控件创建一个新的组别。
函数icon()返回自定义控件在Qt Designer中使用的图标。这里我们假设IconEditorPlugin有关联的资源文件,里面有一个图标编辑器图像的接口。
函数toolTip() 完成在Qt Designer的控件箱中,当鼠标移动到自定义控件时,显示字符串做为提示。
函数whatsThis()返回Qt Designer显示的“What’s This”提问。
函数isContainer()返回true说明这个控件可以包含其他控件。例如,QFrame可以包含其他控件,则它是一个容器控件。很多Qt控件都可以包含其他控件,但是如果isContainer()返回false,Qt Designer就不允许这个控件包含其他控件了。
Qt Designer调用函数createWidget()创建指定父控件的控件实例。
Q_EXPORT_PLUGIN2()必须在源文件的最后声明,这个宏使Qt Designer能够得到这个插件。第一个参数是这个插件的名字,第二个参数是实现这个插件类的名字。
.pro文件如下:
TEMPLATE        = lib
CONFIG         += designer plugin release
HEADERS         = ../iconeditor/iconeditor.h /
                  iconeditorplugin.h
SOURCES         = ../iconeditor/iconeditor.cpp /
                  iconeditorplugin.cpp
RESOURCES       = iconeditorplugin.qrc
DESTDIR         = $(QTDIR)/plugins/designer
.pro文件假定环境变量QTDIR位于Qt的安装目录。在运行make或者nmake编译插件后,程序自动它安装到Qt Designer的plugins目录中。安装成功后,我们就能象其他控件一样在Qt Designer中使用IconEditor控件了。
如果想在Qt Designer集成多个自定义控件,你可以为每个控件创建一个的插件,也可以把所有控件组合到一个插件中,从QDesignerCustomWidgetCollectionInterface派生。

原来这个是从《C++ GUI Programming with Qt 4》翻译过来的。看了下书上这部分,提到2个方法,于是尝试插件法,一番尝试之后,安装新插件到QT Designer了,效果不错。(小插曲: plugin文件也要包含<QtGUI>,否则gcc不认识QEXPORT_PLUGIN2()

另外,我急于求成, 看人家怎么写的自定义widget,漏掉了Q_PROPERTY(QColor penColor READ penColor WRITE setPenColor)这种声明,又折腾了一番。

  最后,在准备把插件导入eclipse之前,尝试把Q_PROPERTY()宏放到vclicklabel类定义中去,然后自己在eclipse内置Qt Designer中添加属性,名称与类中声明一致(_text _pixmap),虽然预览看不到图和文字,运行起来可以看到图和文字。 注意到自己加的叫dynamic property,猜想是运行时动态加上的属性。