目标:使用qt实现一个这样的页面
原型如下,是用html,css做的
这是参考网址:
(天气,天气预报查询,24小时,今天,明天,未来一周7天,10天,15天,40天查询_2345天气王 )
小感想:qss比qpainter用得方便,但比较死板,有些功能不易实现。两者搭配使用,可能会有不一般的效果。
遇到了一些问题,经过许多尝试,最终几乎实现。
1. 实现小widget:
1.1
每个小widget都有两种状态:选中和被选中
所以我们可以使用两个样式表对不同的状态进行管理(但是两个样式表几乎一样)
void Widget::setSelected(bool s)
{
selected=s;
//两种情况下的样式表
if(selected){
QFile file(":/selected.qss");
if(file.open(QFile::ReadOnly)){
QString styleSheet=tr(file.readAll());
ui->widget_2->setStyleSheet(styleSheet);
}
}
else{
QFile file(":/1.qss");
if(file.open(QFile::ReadOnly)){
QString styleSheet=tr(file.readAll());
ui->widget_2->setStyleSheet(styleSheet);
}
}
}
1.2
再一个就是悬浮在图标上时图标被放大一些(一点点):
使用事件过滤器管理
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
if(watched==ui->pic){
if(event->type()==QEvent::Leave){
ui->pic->setFixedSize(QSize(60,60));
}
else if(event->type()==QEvent::Enter){
ui->pic->setFixedSize(QSize(70,70));
}
}
return QWidget::eventFilter(watched,event);
}
2.现在回到大widget中:
2.1
如何获取父widget下的子widget呢?
QList<T> QObject::findChildren(const QString &name = QString(), Qt::FindChildO ptions options = Qt::FindChildrenRecursively) const Qt官方给的例子:查询parentWidget下的所有QPushButton类 QList<QPushButton *> allPButtons = parentWidget.findChildren<QPushButton *>(); 这是我在这个程序中使用的: allwidgets=findChildren<Widget *>();
2.2
对我来讲,难点是如何在把鼠标放上一个小widget时,它就被选中,然后显示对应的蓝色边框和下面的竖线。
(1)如何在把鼠标放上一个小widget时,它就被选中
(依然使用事件过滤器)
bool weatherbar::eventFilter(QObject *watched, QEvent *event)
{
//进入时,会接收到。
//最后进入的是哪个,哪个就被selected
for(int i=0;i<allwidgets.count();++i)
{
Widget * a=allwidgets.at(i);
if(watched==a){
if(event->type()==QEvent::Enter){
//qDebug()<<a<<"entered";
allwidgets.at(num)->setSelected(false);
num=i;
a->setSelected(true);
update();
}
}
}
return QWidget::eventFilter(watched,event);
}
(2)显示对应的蓝色边框和下面的竖线。
为了尽量和原图一致,我使用了重绘事件。
画了5条线和4段小圆弧,思路简单,操作有点麻烦。
void weatherbar::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.save();
painter.translate(0,ui->widget->y()+ui->widget->height());
QPen pen;
pen.setWidth(6);
pen.setColor(QColor(227, 240, 255));
//pen.setJoinStyle(Qt::RoundJoin);
painter.setPen(pen);
QPointF point0,point5;
QPointF point1,point2,point3,point4;
Widget * wid=allwidgets.at(num);
int x=wid->x();
int w=wid->width();
int h=wid->height();
point0=QPointF(0,0);
point5=QPointF(width(),0);
point1=QPointF(x,0);
point2=QPointF(x,-h);
point3=QPointF(x+w,-h);
point4=QPointF(x+w,0);
//填充浅蓝色背景
painter.fillRect(x,-h,w,h,QColor(247, 252, 255));
//painter.drawPolyline(points,6);
qreal radius=30;//把它当成宽和高
QRect r1(point1.x()-radius,point1.y()-radius,radius,radius);
QRect r2(point2.x(),point2.y(),radius,radius);
QRect r3(point3.x()-radius,point3.y(),radius,radius);
QRect r4(point4.x(),point4.y()-radius,radius,radius);
//圆角的实现
painter.drawArc(r1,270*16,90*16);
painter.drawArc(r2,90*16,90*16);
painter.drawArc(r3,0*16,90*16);
painter.drawArc(r4,180*16,90*16);
//画线
painter.drawLine(QPointF(0,0),QPointF(x-radius/2,0));
painter.drawLine(QPointF(x,-radius/2),QPointF(x,-(h-radius/2)));
painter.drawLine(QPointF(x+radius/2,-h),QPointF(x+w-radius/2,-h));
painter.drawLine(QPointF(x+w,-h+radius/2),QPointF(x+w,-radius/2));
painter.drawLine(QPointF(x+w+radius/2,0),QPointF(width(),0));
painter.restore();
QWidget::paintEvent(event);
}