自定义Qt窗口部件

实现一个十六进制的SpinBox,一般SpinBox只支持十进制整数,但是可以子类化方法实现该功能
需重新实现以下虚函数
  1. virtual QString textFromValue ( int value ) const
  2. virtual int valueFromText ( const QString & text ) const

例如:(摘抄自QtAssitant)

  1. int IconSizeSpinBox::valueFromText(const QString &text) const
  2. {
  3. QRegExp regExp(tr("(\\d+)(\\s*[xx]\\s*\\d+)?"));
  4.  
  5. if (regExp.exactMatch(text)) {
  6. return regExp.cap(1).toInt();
  7. } else {
  8. return 0;
  9. }
  10. }
  11.  
  12. QString IconSizeSpinBox::textFromValue(int value) const
  13. {
  14. return tr("%1 x %1").arg(value);
  15. }

自己实现hexspinBox的代码

  1. #ifndef HEXSPINBOX_H
  2. #define HEXSPINBOX_H
  3.  
  4. #include <QSpinBox>
  5.  
  6. class QRegExpValidator;
  7. class hexspinBox : public QSpinBox
  8. {
  9. Q_OBJECT
  10.  
  11. public:
  12. explicit hexspinBox(QWidget *parent = 0);
  13. ~hexspinBox();
  14.  
  15. protected:
  16. //重写基类函数
  17. QValidator::State validate(QString &input, int &pos) const;
  18. int valueFromText(const QString &text) const;
  19. QString textFromValue(int val) const;
  20. private:
  21. QRegExpValidator *validator;
  22.  
  23. };
  24.  
  25. #endif // HEXSPINBOX_H

//实现代码

  1. #include "hexspinbox.h"
  2. #include <QSpinBox>
  3.  
  4. hexspinBox::hexspinBox(QWidget *parent) :
  5. QSpinBox(parent)
  6. {
  7. setRange(0, 255);
  8. validator = new QRegExpValidator(QRegExp("[0-9A-Fa-F]{0, 8}"), this);
  9. }
  10.  
  11. QValidator::State hexspinBox::validate(QString &input, int &pos) const{
  12. return validator->validate(input, pos);
  13. }
  14.  
  15. QString hexspinBox::textFromValue(int val) const{
  16. return QString::number(val, 16).toUpper();
  17. }
  18.  
  19. int hexspinBox::valueFromText(const QString &text) const{
  20. bool ok;
  21. return text.toInt(&ok, 16);
  22. }

子类化QWidget

当手里没有任何一个Qt窗口部件能够满足任何任务需求时,我们可以创建自己想要的窗口部件。要实现这一点,只需通过子类化QWidget,并且通过重新实现一些用来绘制窗口部件和相应鼠标点击的事件处理器即可

比如继承QWidget类
例如,创建一个可以改变区域颜色的简单图形界面程序
先让主类继承QWidget,在重写需要自己实现的虚函数,如下面的 mousePressEvent , mouseMoveEvent, paintEvent
  1. class IconEditor : public QWidget
  2. {
  3. Q_OBJECT
  4. //声明类的属性
  5. Q_PROPERTY(QColor penColor READ penColor WRITE setPenColor)
  6. Q_PROPERTY(QImage iconImage READ iconImage WRITE setIconImage)
  7. Q_PROPERTY(int zoomFactor READ zoomFactor WRITE setZoomFactor)
  8.  
  9. public:
  10. explicit IconEditor(QWidget *parent = 0);
  11. ~IconEditor();
  12.  
  13. void setPenColor(const QColor &newColor);
  14. QColor penColor() const { return curColor; }
  15. void setZoomFactor(int newZoom);
  16. int zoomFactor() const { return zoom; }
  17. void setIconImage(const QImage &newImage);
  18. QImage iconImage() const { return image; }
  19. QSize sizeHint() const;
  20.  
  21. protected:
  22. void mousePressEvent(QMouseEvent *);
  23. void mouseMoveEvent(QMouseEvent *);
  24. void paintEvent(QPaintEvent *);
  25.  
  26. private:
  27. void setImagePixel(const QPoint &pos, bool opaque);
  28. QRect pixelRect(int i, int j) const;
  29.  
  30. QColor curColor;
  31. QImage image;
  32. int zoom;
  33. };

再依次实现类中的函数,与MFC中自绘控件是一回事。以下是cpp中部分代码

  1. void IconEditor::paintEvent(QPaintEvent *event){
  2. QPainter painter(this);
  3.  
  4. if(zoom>=3){
  5. painter.setPen(palette().foreground().color());
  6. for(int i=0; i<=image.width(); i++){
  7. painter.drawLine(zoom*i, 0,
  8. zoom*i, zoom*image.height());
  9. for(int j=0; j<=image.height(); j++){
  10. painter.drawLine(0, zoom*j,
  11. zoom*image.width(), zoom*j);
  12. }
  13. for(int i=0; i<image.width(); i++){
  14. for(int j=0; j<image.height(); j++){
  15. QRect rect = pixelRect(i, j);
  16. if(!event->region().intersected(rect).isEmpty()){
  17. QColor color = QColor::fromRgba(image.pixel(i, j));
  18. if(color.alpha()<255)
  19. painter.fillRect(rect, Qt::white);
  20. painter.fillRect(rect, color);
  21. }
  22. }
  23. }
  24. }
  25. }
  26. }
  1. void IconEditor::mousePressEvent(QMouseEvent *event){
  2. if(event->button() == Qt::LeftButton){
  3. setImagePixel(event->pos(), true);
  4. } else if(event->button()==Qt::RightButton){
  5. setImagePixel(event->pos(), false);
  6. }
  7. }
  8.  
  9. void IconEditor::mouseMoveEvent(QMouseEvent *event){
  10. if(event->buttons() & Qt::LeftButton){
  11. setImagePixel(event->pos(), true);
  12. } else if(event->buttons() & Qt::RightButton){
  13. setImagePixel(event->pos(), false);
  14. }
  15. }



程序运行截图:


Qt学习之自定义窗口部件的更多相关文章

  1. 【Qt学习笔记】窗口部件整理

    关于Qt中窗口部件的学习 今天开始学习Qt的窗口部件,领略一下Qt的神奇之处,记得2012年的那年冬天,我还学Java呢,现在基本上和Java说再见了,不过对于嵌入式的开发Qt还是举足轻重的,我想趁着 ...

  2. Qt入门(19)——自定义窗口部件

    我们介绍可以画自己的第一个自定义窗口部件.我们也加入了一个有用的键盘接口.我们添加了一个槽:setRange().        void setRange( int minVal, int maxV ...

  3. Qt自定义窗口部件

    QtDesigner自定义窗口部件有两种方法:改进法(promotion)和插件法(plugin)   改进法   1.改进法之前,要先写好子类化QSpinBox后的HexspinBox.h和Hexs ...

  4. C++ GUI Qt4编程-创建自定义窗口部件

    C++ GUI Qt4编程-创建自定义窗口部件   Qtqt4 通过Qt窗口部件进行子类化或者直接对QWidget进行子类化,就可以创建自定义窗口部件,下面示范两种方式,并且也会说明如何把自定义窗口部 ...

  5. Kivy 中文教程 实例入门 简易画板 (Simple Paint App):1. 自定义窗口部件 (widget)

    1. 框架代码 用 PyCharm 新建一个名为 SimplePaintApp 的项目,然后新建一个名为 simple_paint_app.py 的 Python 源文件, 在代码编辑器中,输入以下框 ...

  6. QT笔记之自定义窗口拖拽移动

    1.QT自定义标题栏,拖拽标题栏移动窗口(只能拖拽标题,其他位置无法拖拽) 方法一: 转载:http://blog.sina.com.cn/s/blog_4ba5b45e0102e83h.html . ...

  7. PyQt(Python+Qt)学习随笔:窗口layout布局的SizeConstraint和部件的大小约束策略sizePolicy不起作用的问题

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 在写一个测试代码时,发现无论怎么设置窗口以及子部件 ...

  8. PyQt(Python+Qt)学习随笔:QWidget部件的palette属性以及ColorGroup、colorRole的用途和含义

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 1.palette属性 QWidget部件的palette属性用于控制 ...

  9. QT5中如何自定义窗口部件

    提升法 eg.(定义一个新的QLable部件)1.定义一个类class Label : public base, public QLabel //可以支持多重继承2.在qt creator中打开ui编 ...

随机推荐

  1. Golang 做的几个跟性能有关的工具

    1.Vegeta https://github.com/tsenart/vegeta Vegeta 是一个万能的 HTTP 负载测试工具,提供命令行工具和一个开发包. 使用方法: $ vegeta a ...

  2. Thread .join 的用法一例

    在使用身份证读卡器时,要求 1. 身份证读到身份证 就 停止线程. 2. 关闭界面时会 自动停止调用读身份证的线程.这时候就需要用到 Thead.join 例子如下: Thread thread; p ...

  3. 闲谈Future模式-订蛋糕

    一. Future模式简介 Future有道翻译:n. 未来:前途:期货:将来时.我觉得用期货来解释比较合适.举个实际生活中例子来说吧,今天我女朋友过生日,我去蛋糕店准备给女朋友定个大蛋糕,超级大的那 ...

  4. keyCode 与charCode

    键盘事件拥有两个属性,keyCode和CharCode,他们之间有一些不一样之处.keyCode表示用户按下键的实际的编码,而charCode是指用户按下字符的编码. IE下 keyCode:对于ke ...

  5. 在Python中怎么表达True

    在Python中怎么表达True   为False的几种情况 0为False,其他所有数值皆为True 空串("")为False,其他所有字符串皆为True 空list([])为F ...

  6. Linux文件系统 (Ubunt)

    Linux 文件系统是linux的一个十分基础的知识,同时也是学习linux的必备知识. 本文将站在一个较高的视图来了解linux的文件系统,主要包括了linux磁盘分区和目录.挂载基本原理.文件存储 ...

  7. HW7.13

    import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...

  8. Uva 10007 / HDU 1131 - Count the Trees (卡特兰数)

     Count the Trees  Another common social inability is known as ACM (Abnormally Compulsive Meditation) ...

  9. Fedora 16设置开机自启动程序与Ubuntu的区别

    Ubuntu设置开机自启动脚本的方法是:修改/etc/init.d/rc.local这个文件,添加需要启动的程序即可,相关函数如下: void SetSysAutoBoot() { ] = {}; ; ...

  10. webrtc 的回声抵消(aec、aecm)算法简介(转)

    webrtc 的回声抵消(aec.aecm)算法简介        webrtc 的回声抵消(aec.aecm)算法主要包括以下几个重要模块:1.回声时延估计 2.NLMS(归一化最小均方自适应算法) ...