1.自定义按钮类
效果:
(1)仅当未选中,未悬浮时
(2)其他三种情况,均如图
#ifndef BTN_H
#define BTN_H
#include <QPushButton>
class btn : public QPushButton
{
Q_OBJECT
public:
btn(QWidget * parent = nullptr);
void set_normal_icon(QString icon);
void set_checked_icon(QString icon);
void init();
protected:
void paintEvent(QPaintEvent *) override;
void enterEvent(QEvent *event);
void leaveEvent(QEvent *event);
private:
QString normal_icon,checked_icon;
//选中,悬浮
bool hover;
};
#endif // BTN_H
#include "btn.h"
#include <QDebug>
#include <QPainter>
#pragma execution_character_set("utf-8")
btn::btn(QWidget * parent ): QPushButton(parent)
{
//正常时,无边框
//被选中时,背景变换+圆角矩形
init();
}
void btn::set_normal_icon(QString icon)
{
normal_icon=icon;
}
void btn::set_checked_icon(QString icon)
{
checked_icon=icon;
}
void btn::init()
{
QSizePolicy sizePolicy1(QSizePolicy::Fixed, QSizePolicy::Fixed);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
sizePolicy1.setHeightForWidth(this->sizePolicy().hasHeightForWidth());
this->setSizePolicy(sizePolicy1);
//宽高
this->setMinimumSize(QSize(75, 75));
this->setMaximumSize(QSize(75, 75));
//可选中
this->setCheckable(true);
hover=false;
}
void btn::enterEvent(QEvent *event)
{
qDebug()<<"进入事件发生";
hover=true;
}
void btn::leaveEvent(QEvent *event)
{
qDebug()<<"离开事件发生";
hover=false;
}
void btn::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing, true);
if(!hover && !this->isChecked()){
//画黑图标
QPixmap pix(normal_icon);
pix=pix.scaled(40,40,Qt::IgnoreAspectRatio);
//75*75,40*40
//(75-40)/2=12.5
QRectF target(12.5, 12.5, 52.5, 52.5);
QRectF source(0.0, 0.0, 40.0, 40.0);
painter.drawPixmap(target,pix,source);
}
else{
//画圆角矩形
QRect rect(0,0,75,75);
painter.setPen(Qt::NoPen);
painter.setBrush(QBrush(QColor(255,255,255)));
painter.drawRoundedRect(rect,10,10,Qt::AbsoluteSize);
//画蓝图标
QPixmap pix(checked_icon);
pix=pix.scaled(40,40,Qt::IgnoreAspectRatio);
//75*75,40*40
//(75-40)/2=12.5
QRectF target(12.5, 12.5, 52.5, 52.5);
QRectF source(0.0, 0.0, 40.0, 40.0);
painter.drawPixmap(target,pix,source);
}
}
2.实验:
label与widget平级,label在widget上面,label显示完全
label在widget里面,label局部显示:
3.自定义按钮类2:
效果:
#ifndef BTN2_H
#define BTN2_H
#include <QPushButton>
class btn2 : public QPushButton
{
Q_OBJECT
public:
btn2(QWidget * parent =nullptr);
void get_icon(QString path);
protected:
void paintEvent(QPaintEvent *) override;
private:
QString icon;
};
#endif // BTN2_H
#include "btn2.h"
#include <QPainter>
#include <QDebug>
#pragma execution_character_set("utf-8")
btn2::btn2(QWidget *parent):
QPushButton(parent)
{
}
void btn2::get_icon(QString path)
{
icon=path;
}
void btn2::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing, true);
//圆角边框
QRect rect(0,0,200,75);
QPen pen;
pen.setColor(QColor(244,244,244));
pen.setWidth(3);
pen.setStyle(Qt::SolidLine);
painter.setPen(pen);
painter.setBrush(QBrush(QColor(255,255,255)));
painter.drawRoundedRect(rect,10,10,Qt::AbsoluteSize);
//蓝色图标
QPixmap pix(icon);
pix=pix.scaled(40,40,Qt::IgnoreAspectRatio);
//75*75,40*40
//(75-40)/2=12.5
QRectF target(12.5, 12.5, 52.5, 52.5);
QRectF source(0.0, 0.0, 40.0, 40.0);
painter.drawPixmap(target,pix,source);
//文字
QFont font;
font.setPointSize(12);
font.setFamily("隶书");
painter.setFont(font);
painter.setPen(QColor(0,0,0));
painter.drawText(52.5,0,200-52.5,75,Qt::AlignCenter,this->text());
}
4.实验:
目标:得到这个蓝色矩形左上角的坐标信息:
pos : QPoint
它返回的是相对于父窗口的偏移位置,而不是最外面的窗口的。
可以使用这个函数来实现目标功能:
QPoint Form::get_pos(QWidget * w)
{
QWidget * p=qobject_cast<QWidget *>(w->parent());
if(p == this){
return w->pos();
}
else{
return w->pos()+get_pos(p);
}
}
5.注意:在初始化函数中去获取目标位置信息,因为这时候都还没有布局好,得到的结果是错误的。
可用方法:
使用定时器延时一下
timer.singleShot(100,this,[=](){
//这样就可以解决输出为0的问题了
for(int i=0;i<btn1.count();++i)
{
btn * one=btn1.at(i);
one->set_absolute_pos(get_pos(one));
qDebug()<<one->get_absolute_pos();
}
});
6.问题:
想实现这样的效果,但延迟比较大,该方案pass,想不出解决办法。
7.QButtonGroup的使用
group=new QButtonGroup(this);
for(int i=0;i<btn1.count();++i)
{
QAbstractButton * b=qobject_cast<QAbstractButton *>(btn1.at(i));
group->addButton(b,i+1);
}
8.去边框
导入这两个文件movable_widget.h,movable_widget.cpp
#ifndef MOVABLE_WIDGET_H
#define MOVABLE_WIDGET_H
#include <QWidget>
class movable_widget:public QWidget
{
public:
movable_widget(QWidget * parent=0);
protected:
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *event);
private:
QPoint Pos;
bool ismoving;
};
#endif // MOVABLE_WIDGET_H
#include "movable_widget.h"
#include <QMouseEvent>
#include <QPainter>
movable_widget::movable_widget(QWidget * parent):
QWidget(parent)
{
setWindowFlag(Qt::FramelessWindowHint);
setAttribute(Qt::WA_TranslucentBackground);
}
void movable_widget::mouseMoveEvent(QMouseEvent *event)
{
if(ismoving)
{
QPoint now=event->globalPos()-Pos;
move(now);
}
QWidget::mouseMoveEvent(event);
}
void movable_widget::mousePressEvent(QMouseEvent *event)
{
if(event->button()==Qt::LeftButton)
{
ismoving=true;
Pos=event->globalPos()-pos();
}
QWidget::mousePressEvent(event);
}
void movable_widget::mouseReleaseEvent(QMouseEvent *event)
{
ismoving=false;
QWidget::mouseReleaseEvent(event);
}
void movable_widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing); // 反锯齿;
painter.setBrush(QBrush(Qt::red));
painter.setPen(Qt::transparent);
QRect rect = this->rect();
rect.setWidth(rect.width() - 1);
rect.setHeight(rect.height() - 1);
painter.drawRoundedRect(rect, 15, 15);
QWidget::paintEvent(event);
}
让目标类继承movable_widget类即可