QT中如何自定义控件(如自定义自己的label)

一尺丈量 2015-11-30 04:29:13
在QT中如何定义控件呢?
比如说现在有一个需求,需要一个这样的控件,它是一个类似label的东西,但可以模拟按钮进行点击操作(如果点击就变颜色)。
当然这样就要有合理的事件处理函数与机制了。事件处理要求写在类里面。
如下面的label,点击可以改变颜色:


上图中有四个自定义的控件(可以视作功能增强的label),点击可以变色。但要要求将事件处理也放在实现类里面。
请各位大神提供思路或者代码。
谢谢
...全文
2233 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
gldcpp 2015-12-01
  • 打赏
  • 举报
回复
点击变色貌似挺简单的效果吧 之前也做过 还有鼠标函数一般都是保护的吧 打成public不大好吧
冷静忍耐 2015-11-30
  • 打赏
  • 举报
回复
引用 9 楼 u010155023 的回复:
[quote=引用 8 楼 u013466477 的回复:] [quote=引用 7 楼 u010155023 的回复:] 是Widget中的事件处理的注释,说错了。
你这写的有点复杂了,写代码最好尽量简化。 QWidget里面所有事件的就不要了,事件不需要传递的。 只需要重写AppLabel的事件就好了,因为你点击的是AppLabel。 [/quote] 事实上,如果只重写AppLabel中的的事件处理,那么在程序启动完成后,AppLabel就再也无法接收到消息了。[/quote] 看错了,是因为鼠标点在你AppLabel的label上了,所以AppLabel不响应事件,里面的label才响应
一尺丈量 2015-11-30
  • 打赏
  • 举报
回复
引用 8 楼 u013466477 的回复:
[quote=引用 7 楼 u010155023 的回复:] 是Widget中的事件处理的注释,说错了。
你这写的有点复杂了,写代码最好尽量简化。 QWidget里面所有事件的就不要了,事件不需要传递的。 只需要重写AppLabel的事件就好了,因为你点击的是AppLabel。 [/quote] 事实上,如果只重写AppLabel中的的事件处理,那么在程序启动完成后,AppLabel就再也无法接收到消息了。
冷静忍耐 2015-11-30
  • 打赏
  • 举报
回复
引用 7 楼 u010155023 的回复:
是Widget中的事件处理的注释,说错了。
你这写的有点复杂了,写代码最好尽量简化。 QWidget里面所有事件的就不要了,事件不需要传递的。 只需要重写AppLabel的事件就好了,因为你点击的是AppLabel。
一尺丈量 2015-11-30
  • 打赏
  • 举报
回复
是Widget中的事件处理的注释,说错了。
一尺丈量 2015-11-30
  • 打赏
  • 举报
回复
引用 4 楼 u013466477 的回复:
[quote=引用 2 楼 u010155023 的回复:] [quote=引用 1 楼 u013466477 的回复:] 你上个问题好像已经解决了吧
“别人说用线程可以解决。。。。。。现在有两个问题了”。 [/quote] 用线程啊??难道我理解错了吗 你想要的就是点击自定义Label就变颜色吗?[/quote] 开个玩笑。怎么会用到线程。说一下我的设计吧 一共有两个类:首先是Widget,继续自QWidget。 头文件为:
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QLabel>
#include <QVector>
#include "applabel.h"


class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    explicit Widget(qint32 label_amount, QWidget *parent = 0);
    ~Widget();
public:
    void addWidget(AppLabel *label);
    void rePlace();
    bool event(QEvent *);
    void mousePressEvent(QMouseEvent *);
    void mouseReleaseEvent(QMouseEvent *);
    qint32 index(QRect geometry, int width);
private:
    qint32 _lbl_amount;
    qint32 _lbl_bottom_Single_width;
    qint32 _lbl_height;
    QVector<AppLabel *> _labels;

};

#endif // WIDGET_H
其中_labels这个vector是用来装AppLabel的。 AppLabel的头文件为:
#ifndef APPBUTTON_H
#define APPBUTTON_H

#include <QWidget>
#include <QLabel>
#include <QEvent>
#include <QMouseEvent>


class AppLabel : public QWidget
{
    Q_OBJECT
public:
    explicit AppLabel(QWidget *parent = 0);
    explicit AppLabel(QString text, QWidget *parent = 0);
private:
    QLabel *_label;//main object.
public:
    void resize(const QSize &size);
    void resize(int w, int h);
    QSize size();

    void setGeometry(QRect rect);
    void setGeometry(int x, int y, int w, int h);
    QRect geometry();

    Qt::TextFormat textFormat() const;
    void setTextFormat(Qt::TextFormat text_format);

    Qt::Alignment alignment() const;
    void setAlignment(Qt::Alignment alignment);

    int frameStyle() const;
    void setFrameStyle(int frame_style);

    int margin() const;
    void setMargin(int margin);

    void setStyleSheet(const QString& style_sheet);
    QString styleSheet() const;
    void setParent(QWidget *parent);
    void show();

public:
    bool event(QEvent *);
    void mousePressEvent(QMouseEvent *);
    void mouseReleaseEvent(QMouseEvent *);
signals:

public slots:

};

#endif // APPBUTTON_H
它事实上是一个label,通过里面声明一个QLabel来实现(继续自QWidget)。但不同的是重写了事件处理函数。 两个类都重写了事件处理函数。思想是这样的。通过Widget中的事件处理将事件信号发送到AppLabel中去。然后AppLabel来进行事件响应逻辑。但不知道为什么AppLabel中的事件不能正常响应。下面分别是两个类的实现
#include "widget.h"
#include <QDebug>
#include <QEvent>
#include <QMouseEvent>

Widget::Widget(QWidget *parent) :
    QWidget(parent)
{
    this->_lbl_amount = 0;
    this->_lbl_height = 80;
}

Widget::Widget(qint32 label_amount, QWidget *parent):
    QWidget(parent)
{
    this->_lbl_amount = label_amount;
    this->_lbl_height = 80;
}

Widget::~Widget()
{

}
void Widget::addWidget(AppLabel *label)
{
    ++this->_lbl_amount;
    this->_lbl_bottom_Single_width = this->width() / this->_lbl_amount;
    label->setParent(this);

    _labels.push_back(label);
    label->setAlignment(Qt::AlignVCenter|Qt::AlignHCenter);
    label->setFrameStyle(QFrame::Panel | QFrame::Sunken);
    QString style("background-color:#DFDDDE;");
    //connect(label, SIGNAL(clicked()), this, SLOT());
    label->setStyleSheet(style);
    this->rePlace();
}

void Widget::rePlace()
{
    for (qint32 i = 0; i < this->_labels.size(); ++i)
    {
        //this->_labels.at(i)->width(this->_lbl_bottom_Single_width);
        //this->_labels.at(i)->height(this->_lbl_height);
        this->_labels.at(i)->setGeometry(i * (this->_lbl_bottom_Single_width),
                                         this->height() - this->_lbl_height,
                                         this->_lbl_bottom_Single_width,
                                         this->_lbl_height);
        this->_labels.at(i)->show();
    }
}

qint32 Widget::index(QRect geometry, int width)
{
    int x = geometry.width();
    return x / width;
}

bool Widget::event(QEvent *event)
{
    //event->accept();
    if (this->_labels.size() == 4)
    {
        //if (event->type() == QEvent::MouseButtonDblClick ||
        //        event->type() == QEvent::MouseButtonPress ||
        //        event->type()==QEvent::MouseButtonRelease)
        //{
            //QMouseEvent *me = (QMouseEvent *)event;
            //qDebug()<<me->pos();
            //qDebug()<<me->x() / this->_lbl_bottom_Single_width;
            return this->_labels[0]->event(event);
        //}
    }
    else
    {
        return QWidget::event(event);
    }
}

void Widget::mousePressEvent(QMouseEvent *)
{
    qDebug()<<"Widget mouse press event.";
}

void Widget::mouseReleaseEvent(QMouseEvent *)
{
    qDebug()<<"Widget mouse release event.";
}
AppLabel类
#include "applabel.h"
#include <QMessageBox>
#include <QDebug>

AppLabel::AppLabel(QWidget *parent) :
    QWidget(parent)
{
    this->_label = new QLabel(parent);
}

AppLabel::AppLabel(QString text, QWidget *parent):
    QWidget(parent)
{
    this->_label = new QLabel(text, parent);
    //this->_label->setAlignment(Qt::AlignVCenter|Qt::AlignHCenter);
    //this->_label->setFrameStyle(QFrame::Panel | QFrame::Sunken);
    //this->_label->resize(240,80);
}

void AppLabel::resize(const QSize &size)
{
    QWidget::resize(size);
    this->_label->resize(size);
}
void AppLabel::resize(int w, int h)
{
    QWidget::resize(w, h);
    this->_label->resize(w, h);
}

QSize AppLabel::size()
{
    return this->_label->size();
}

void AppLabel::setGeometry(QRect rect)
{
    QWidget::setGeometry(rect);
    this->_label->setGeometry(rect);
}
void AppLabel::setGeometry(int x, int y, int w, int h)
{
    QWidget::setGeometry(x, y, w, h);
    this->_label->setGeometry(x, y, w, h);
}
QRect AppLabel::geometry()
{
    return this->_label->geometry();
}

Qt::TextFormat AppLabel::textFormat() const
{
    return this->_label->textFormat();
}
void AppLabel::setTextFormat(Qt::TextFormat text_format)
{
    this->_label->setTextFormat(text_format);
}

Qt::Alignment AppLabel::alignment() const
{
    return this->_label->alignment();
}
void AppLabel::setAlignment(Qt::Alignment alignment)
{
    return this->_label->setAlignment(alignment);
}

int AppLabel::frameStyle() const
{
    return this->_label->frameStyle();
}
void AppLabel::setFrameStyle(int frame_style)
{
    this->_label->setFrameStyle(frame_style);
}

int AppLabel::margin() const
{
    return this->_label->margin();
}
void AppLabel::setMargin(int margin)
{
    return this->_label->setMargin(margin);
}

void AppLabel::setStyleSheet(const QString& style_sheet)
{
    //this->setStyleSheet("background-color:#2B2032;");
    //QWidget::setStyleSheet("background-color:transparent;");
    this->_label->setStyleSheet(style_sheet);
}
QString AppLabel::styleSheet() const
{
    return this->_label->styleSheet();
}

void AppLabel::setParent(QWidget *parent)
{
    QWidget::setParent(parent);//如果没有这句,那就很有问题(至少setStyleSheet不会立刻生效。)
    this->_label->setParent(parent);
}
void AppLabel::show()
{
    this->_label->show();
}

bool AppLabel::event(QEvent *event)
{
    //event->accept();
    qDebug()<<"Test here.";
    qDebug()<<event->type();
    return QWidget::event(event);
}

void AppLabel::mousePressEvent(QMouseEvent *event)
{
    //qDebug()<<"click.";
    //qDebug()<<this->size();
    //QMessageBox::warning(0, "tips", "event here." + event->type());
    this->setStyleSheet("background-color:#EBFEFD;");
    this->_label->setAttribute(Qt::WA_StyleSheet);
    //update();
    //repaint();
    //this->_label->repaint();
    qDebug()<<"click2.";
}

void AppLabel::mouseReleaseEvent(QMouseEvent *event)
{
    //qDebug()<<"release.";
    this->setStyleSheet("background-color:#DFDDDE;");
    //update();
    //repaint();
   // this->_label->repaint();
   // qDebug()<<"release2.";
}
关键的应该是AppLabel中的事件处理那里。 主函数如下:
#include "widget.h"
#include <QApplication>
#include <QLabel>
#include "applabel.h"
#include <QDebug>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.resize(540, 780);
    AppLabel *label_trade = new AppLabel("交易");
    AppLabel *label_bus = new AppLabel("Business");
    AppLabel *label_pro = new AppLabel("Products");
    AppLabel *label_mine = new AppLabel("Mine");
    w.addWidget(label_trade);
    w.addWidget(label_bus);
    w.addWidget(label_pro);
    w.addWidget(label_mine);

    //AppLabel *stay = new AppLabel("alone");
    //stay->show();
    //AppLabel app_label("myapplabel", &w);
    w.show();
    return a.exec();
}
大神看看吧。尝试将AppLabel中的event函数中的某些注释去掉,你怎么知道问题所在的了。
冷静忍耐 2015-11-30
  • 打赏
  • 举报
回复
引用 3 楼 u010155023 的回复:
[quote=引用 1 楼 u013466477 的回复:] 你上个问题好像已经解决了吧
大神,加个QQ吧,看你好像在专业刷问题一样,我现在这个问题解决不了。(上一个是解决了,但引出了新的问题) 我的QQ:1010313091[/quote] 公司上不了QQ 回去加
冷静忍耐 2015-11-30
  • 打赏
  • 举报
回复
引用 2 楼 u010155023 的回复:
[quote=引用 1 楼 u013466477 的回复:] 你上个问题好像已经解决了吧
“别人说用线程可以解决。。。。。。现在有两个问题了”。 [/quote] 用线程啊??难道我理解错了吗 你想要的就是点击自定义Label就变颜色吗?
一尺丈量 2015-11-30
  • 打赏
  • 举报
回复
引用 1 楼 u013466477 的回复:
你上个问题好像已经解决了吧
大神,加个QQ吧,看你好像在专业刷问题一样,我现在这个问题解决不了。(上一个是解决了,但引出了新的问题) 我的QQ:1010313091
一尺丈量 2015-11-30
  • 打赏
  • 举报
回复
引用 1 楼 u013466477 的回复:
你上个问题好像已经解决了吧
“别人说用线程可以解决。。。。。。现在有两个问题了”。
冷静忍耐 2015-11-30
  • 打赏
  • 举报
回复
你上个问题好像已经解决了吧

16,216

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧