QT自定义控件(左右方向弹出控件)
自定义控件存在的意义 :QT 内置控件丑,而且满足不了有些实际开发的需求。所以需要编写自定义控件来完成一些特殊需求。
效果展示
- 界面说明 :点击右侧中间的按钮会从左边或者右边弹出一个窗体,这个窗体还可以自定义。
- 功能说明 :单击按钮窗体弹出,再次单击窗体消失
- 补充说明:弹窗可自定义成任意控件。亦可以设置按钮与弹窗之间的 距离
代码:
// 自定义弹出窗体(其中的 myCalendar控件是自定义日历控件,请看我另一篇文章日历控件)
class toolWidget:public QWidget
{
Q_OBJECT
public:
toolWidget(QWidget*widget,int pos); // 控件类型 名字 弹出方向 0 left 1 right
void createWidget();
//virtual void additem()=0;
void setWidgetInfo(QString name);
void setWidStyle(QString name);
signals:
void SigtoolWidget(int type);
void SigListWidgetTextChanged(QString);
void SigListWidgetDoubleClicked();
void SigMyCalendarOkBtnClicked(QString);
public:
QWidget*m_widget;
int m_pos;
int m_type;
QString m_objName;
};
toolWidget::toolWidget(QWidget*widget,int pos):m_widget(widget),m_pos(pos)
{
// obj->metaObject()->className() == QStringLiteral("QPushButton") // 判断是不是QPushButton
m_objName =widget->metaObject()->className();
createWidget();
}
void toolWidget::createWidget()
{
if(!m_widget)
{
return;
}
m_widget->setParent(this);
QHBoxLayout*lay = new QHBoxLayout();
lay->addWidget(m_widget);
lay->setContentsMargins(1,1,1,1);
this->setLayout(lay);
}
void toolWidget::setWidgetInfo(QString name)
{
// 设置样式
setWidStyle(name);
// 曹函数响应
}
void toolWidget::setWidStyle(QString name)
{
if(name == "QListWidget")
{
this->setStyleSheet("QWidget{background-color: rgb(233, 185, 110);border:3px solid gray;padding:3px 3px 3px 3px;}"
"QListWidget::item{color: rgb(78, 154, 6);height:20px;padding-left:5px;}"
"QListWidget::item:hover{color: rgb(92, 53, 102);}"
"QListWidget::item::selected:active{color:red;border-width:10;}"
"QListWidget::item:selected{color:red;border-width:10;}"
);
}
}
// 自定义按钮窗体
class myButton : public QToolButton
{
Q_OBJECT
public:
explicit myButton(QWidget *parent = nullptr);
~myButton();
//myButton(QWidget *parent = nullptr,int pos=0);
public:
void initWidgetInfo();
void toolWidgetCmd(QString name);
void createTool(toolWidget*tools);
void mousePressEvent(QMouseEvent *);
void resizeEvent(QResizeEvent*);
void moveEvent(QMoveEvent *);
void myMoveEvent();
void hideEvent(QHideEvent*);
void setListParent(QWidget*parent);
void setItemWidgetPos(int pos);
void setSpacting(int spacing);
void dealWithAnimation();
void widgetMove(int x,int y);
signals:
public slots:
void SlottoolWidget(int);
private:
//QListWidget *m_list;
toolWidget *m_list;
int m_pos;
int m_spacing = 0;
};
myButton::myButton(QWidget *parent) : QToolButton(parent)
,m_list(NULL)
{
//this->setListParent(parent);
//this->setFixedSize(100,40);
m_pos =1;
m_spacing = 2;
this->setStyleSheet("QWidget{background-color: rgb(233, 185, 110);color:green;border:3px solid gray;padding:3px 3px 3px 3px;}");
}
myButton::~myButton()
{
if(m_list)
{
delete m_list;
m_list = NULL;
}
}
void myButton::createTool(toolWidget*tools)
{
if(!tools)
{
return;
}
if(!m_list)
{
m_list = tools;
}
initWidgetInfo();
}
void myButton::initWidgetInfo()
{
this->m_pos = m_list->m_pos;
m_list->resize(this->width(),this->height()*6);
QPoint point =this->mapToGlobal(QPoint(0,0));
m_list->move(point.x(),point.y());
m_list->setWindowFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint);// 顶层无边框窗体
m_list->hide();
m_list->setWidgetInfo(m_list->m_objName);
toolWidgetCmd(m_list->m_objName);
}
void myButton::toolWidgetCmd(QString name)
{
if(name == "QListWidget")
{
QListWidget*tlist = qobject_cast<QListWidget*>(m_list->m_widget);
connect(tlist,&QListWidget::currentTextChanged,[=](QString text){
this->setText(text);
});
connect(tlist,&QListWidget::doubleClicked,[=](){
m_list->hide();
});
}
}
void myButton::setItemWidgetPos(int pos)
{
m_pos = pos;
}
void myButton::setSpacting(int spacing)
{
m_spacing = spacing;
}
void myButton::hideEvent(QHideEvent *)
{
if(m_list)
{
if(m_list->isVisible())
{
m_list->hide();
}
}
}
void myButton::moveEvent(QMoveEvent *)
{
qDebug()<<"moveEvent!";
if(!m_list)
{
return;
}
int x = 0,y=0;
QPoint point =this->mapToGlobal(QPoint(0,0));
if(m_pos == 0) // left
{
x= point.x()-this->width()-m_list->width()-m_spacing;
}
else //right
{
x = point.x()+m_spacing;
}
y = point.y()-m_list->height()/2+this->height()/2;
m_list->move(this->width()+x,y);
//m_list->move(0,0);
}
void myButton::myMoveEvent()
{
qDebug()<<"mymoveEvent!";
if(!m_list)
{
return;
}
int x = 0,y=0;
QPoint point =this->mapToGlobal(QPoint(0,0));
if(m_pos == 0) // left
{
x= point.x()-this->width()-m_list->width()-m_spacing;
}
else //right
{
x = point.x()+m_spacing;
}
y = point.y()-m_list->height()/2+this->height()/2;
m_list->move(this->width()+x,y);
}
void myButton::setListParent(QWidget *parent)
{
if(!m_list||!parent)
{
return;
}
m_list->setParent(parent);
}
void myButton::mousePressEvent(QMouseEvent *)
{
if(!m_list)
{
return;
}
if(!m_list->isVisible())
{
int x = 0,y =0;
QPoint point =this->mapToGlobal(QPoint(0,0));
if(m_pos==0)
{
//x= this->x()-this->width()-m_list->width()-m_spacing;
x = point.x()-m_list->width()-m_spacing;
y = point.y()-m_list->height()/2+this->height()/2;
m_list->move(x,y);
m_list->show();
QPropertyAnimation *animation= new QPropertyAnimation(m_list,"geometry");
animation->setDuration(200);
animation->setStartValue(QRect(m_list->pos().x()+m_list->width(),m_list->pos().y(),m_list->width(),m_list->height()));
animation->setEndValue(QRect(m_list->pos().x(),m_list->pos().y(),m_list->width(),m_list->height()));
animation->start();
}
else
{
x =point.x()+m_spacing+m_list->width();
y = point.y()-m_list->height()/2+this->height()/2;
m_list->move(x,y);
m_list->show();
QPropertyAnimation *animation= new QPropertyAnimation(m_list,"geometry");
animation->setDuration(200);
animation->setStartValue(QRect(x-m_list->width(),m_list->pos().y(),m_list->width(),m_list->height()));
animation->setEndValue(QRect(x,m_list->pos().y(),m_list->width(),m_list->height()));
animation->start();
}
}
else
{
m_list->hide();
}
}
void myButton::resizeEvent(QResizeEvent *)
{
m_list->resize(this->width(),this->height()*6);
}
void myButton::widgetMove(int x, int y)
{
qDebug()<<"-------->";
if(!m_list)
{
return;
}
int x1 = x-m_list->width()-m_spacing;
int y1 = y-m_list->height()/2+this->height()/2;
m_list->move(x1,y1);
}
void myButton::SlottoolWidget(int type)
{
if(type == 0)
{
}
}
//调用 设置好目标属性后扔进toolwidget
void run()
{
QListWidget*widget = new QListWidget;
for(int i = 0;i<6;++i)
{
widget->addItem(QString::number(i));
}
//控件, 弹窗方向( 0左边其他右边)
ui->toolButton->createTool(new toolWidget(widget,0));
}