再续前缘
噗嗤。
就是补充一下首版本,加一丢丢东西。
总所周知,首版本都是匆匆忙忙,事后就看看有什么可以细细记录一下和补充一下。
好吧,其实也不多。
效果速看
- 新增随着窗口大小改动而改变大小的效果
- 新增鼠标控制
- 处理图片少于五张的情景
- 添加测试背景
内容细看
啊哈哈哈哈哈哈哈哈哈哈哈嗝,上面有内味没?有得一哈哈哈哈哈好专业啊哈哈哈哈哈嗝。
算了算了认真点,
如虎添翼,锦上添花,雪中送炭
嗯嗯这些都是必须滴。
1.搞清楚定位
首先本来就是设计成一个控件库内容的,所以就继承widget了和dialog没有任何关系了。
那么测试或者说看效果呢?就直接搞一个mainwindow然后把弄好的carousel widget新建放上去就行了。
2.图片
新建一个资源随便放几张进去,轮播图里是有一个图片列表的,而且图片链表的顺序十分重要。
虽然永远只有5张被加载,但图片链表永远都在那里,顺序遵循左移或右移的操作。
所以配合上一点,加起来就是:
ui->setupUi(this);
QList<QImage *> imgList;
for (int i = 1; i < 7; i++){
QImage* img = new QImage;
img->load(QString(":/img/%1.jpg").arg(i));
imgList << img;
}
carousel = new CarouselWidget(this);
carousel->setGeometry(this->geometry());
carousel->setImageList(imgList);
这个ui就是qmainwindow了,里面就放一个轮播图就完了。
至于setImageList是轮播图代码里的内容,接受一个图片链表。
问题来了,图片多于5张是没问题的,就算是7、8、9张,但由于无论是几张链表结构都是在保持顺序的左移右移的就不担心了,那么平时只加载这个图片链表的前五张就可以了。当然也可以不移动图片链表顺序,换来之的是加载图片的下标要及时更新,现在想想,两种还都可以。
但图片少于五张的情况没考虑啊!
好的细细分一下:
0张:别建轮播图了别建了有什么意义。。。
1张:别轮播了别轮播了就一张播什么。。。
2张、3张、4张,诶这个就有问题了,空的地方怎么办?想着直接填充剩下的就好了。
比如图片只有三张123,那么就自动插入图片12312形成五张图片的效果。但是看到这个顺序最后的那个2没?它的左边是1,右边也是1,所以当它在中间时两边都为1,这样看起来好像不太恰当,所以把列表弄成123123,也就是把原先的图片x2就行了。
有考虑到两张图片的情况,x2只有四张,那就x3吧。如两张图片12,转化成列表就是121212了。这没有问题。
至于尾数?肯定就是取余操作啦!那么综上这个设置图片列表函数就是:
void CarouselWidget::setImageList(QList<QImage *> list){
if (list.count() == 1){
ui->labelLeftPrepare->hide();
ui->labelLeft->hide();
ui->labelRight->hide();
ui->labelRightPrepare->hide();
currentIndex = 0;
mImageList = list;
}else if (list.count() < 5){
for (int i = 0; i < list.count()*3; i++){
mImageList << list.at(i % (list.count()));
currentIndex = list.count()/2;
}
}else{
mImageList = list;
}
initButtons(list.count());
refreshLabelImg();
}
还有图片的比例、分辨率问题,这个qt里面有弄好的就是这个:
QImage scaled(const QSize &s, Qt::AspectRatioMode aspectMode = Qt::IgnoreAspectRatio,Qt::TransformationMode mode = Qt::FastTransformation) const;
前两个参数一般是写入控件的大小长宽,后面的参数就是选择分辨率适应模式
看一下有三个:
enum AspectRatioMode {
IgnoreAspectRatio,
KeepAspectRatio,
KeepAspectRatioByExpanding
};
其实也可以都试一下看一看效果,第一个就是无视原图片比例直接填充满,第二个保持原比例并不超出给的矩形长宽,第三个也是保持长宽比,而且会尽量缩放成给定矩形的最大比例。
话不多说,还是网图靠谱:
3.鼠标拖动
目前控制左移右移的只有下面的按钮而已,加一个鼠标拖动吧还是。
就平时习惯的那样点击然后向左向右拉,只不过正常来说应该在拉的同时图片会移动一点点,拉超过一段距离才移动完全。不过这个动态过程就算了哈哈哈哈不适合,大可不必。。
这里就加一个mousePressEvent和mouseReleaseEvent模仿拖动事件吧。
这个就没什么大问题了,都能得到发生事件的鼠标坐标然后判断一下就行了。如:
if (event->button() == Qt::LeftButton && event->pos().y() < mPicLabelWidth){
pressPoint = event->pos();
}
也要加一点区域判断,就是必须点在哪里才有效果等等。
4.窗口变动
额因为label都会在移动的,所以加布局不合适。
由于没有加布局,所以现在的位置和大小都是定死的。
想要当随窗口大小变动而变动的时候,就要手动加resizeevent(),这个事件会随着widget窗口大小变动而自动调用。
在调试的mainwindow添加resizeevent,也就是在轮播图的parent widget中加入:
void MainWindow::resizeEvent(QResizeEvent* size)
{
if (carousel){
carousel->resize(size->size().width(), size->size().width()/3);
}
}
这个resize会调用carousel的resizeevent,而轮播图就需要重新设置一下那五个固定的预备rect的大小位置,重设一下Label和Image,就行了:
void CarouselWidget::resizeEvent(QResizeEvent* size)
{
mPicLabelWidth = (this->width() - (mPicIntervals*2)) / 3;
refreshRectSize();
refreshLabelImg();
}
Over!
结束!拜拜了您内