亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

QT(9)自定義layout[2] - Flow Layout

系統 1949 0

在上一次學習 QT(8)變動布局Dynamic Layout中,我們在此總結一下:對于修改布局,可以通過removeWidget后在根據新的位置重新加載。為了創建新的合適的布局,我們需要重新resize布局的大小。我們需要注意到在修訂時,要考慮組建之間的空間,即spacing()。對如刪和增都需要考慮QSize(spacing(),spacing())。

在本次,我們延續QT(7)的學習,再次對layout的繼承進行學習。參考 http://doc.qt.nokia.com/latest/layouts-flowlayout.html /。在此之前,我們對QT編譯中碰到的一些問題進行記錄:

問題1:編譯中出現make : g++沒有找到

對于ubuntu可以使用apt-get install g++,但是在采用yum的系統,例如MeeGo,沒有g++的包,yum那里采用了另外的名字yum install gcc-c++。

問題2:編譯中出現undefined reference to `vtable for xxxx(某個類名)'

出去這種情況,需要檢查*.pro文件,看看是否將所需的*.h和*.cpp加入,或者加入一些空文件。

記錄1:制定moc生成文件存放的目錄

moc命令將含Q_OBJECT的頭文件轉換成標準.h文件,在我們定義Q_OBJECT后,很可能會生成moc_xxxxx.cpp的文件。方式:MOC_DIR = build。

言歸正卷,我們這次建立一個自定的layout,上面的widget,根據我們addWidget的先后順序,從左向右排序,如果超過范圍,就從下一排開始,也是從左向右,很像現代文字的書寫方式。如圖所示:

QT(9)自定義layout[2] - Flow Layout QT(9)自定義layout[2] - Flow Layout

搭建程序框架

qtmain.cpp為主程序,mywindow.h和mywindow.cpp為窗口類,flowlayout.h和flowlayout.cpp是我們用于構造我們布局QLayout的子類。mywindow.cpp如下:

MyWindow :: MyWindow()
{
FlowLayout * layout = new FlowLayout();
layout->addWidget (new QPushButton(tr("Short")));
layout->addWidget (new QPushButton(tr("Longer")));
layout->addWidget (new QPushButton(tr("Different Text")));
layout->addWidget (new QPushButton(tr("More Text")));
layout->addWidget (new QPushButton(tr("This is a long text button!")));
setLayout(layout);
setWindowTitle("FlowLayout Test!");
}

構造自定義的布局QLayout子類:存放QLayoutItem

我們在QT(7)中學習過,這里我們使用一個QList<QLayoutItem *> itemList來存放我們的item,并且進行了addItem,count,itemAt(int index),takeAt(int index)這幾個virtual方法,同時在釋放方法~FlowLayout()中清空itemList,并釋放空間。這里,將并在詳細說明。可以參見參考中給出的 源代碼

完成構建函數

在MyWindow類中,我們并不需要有特別的構造函數。在Layout中,計算margin,也就是各widget之間的空隙是一個很麻煩的事情。在例子中,我們提供可定制margin(缺省值為11,由于缺省的邊框為1,所以11大抵重視覺角度看就是10px),這是Layout之間的留邊位置,同時我們也設定了組件之間的間隔大小(m_hSpace,m_vSpace),如下:

FlowLayout :: FlowLayout( QWidget * parent, int margin,int hSpacing,int vSpacing )
: QLayout(parent),m_hSpace(hSpacing),m_vSpace(vSpacing)
{
setContentsMargins(margin,margin,margin,margin);
}

這里我們看到一個有趣的寫法,實際上其等同與在方法中運行了:

QLayout(parent);
m_hSpace = hSpacing;
m_vSpace = vSpacing;

給出Layout的尺寸大小

Qt::Orientations FlowLayout::expandingDirections() const
{
return 0;
}

這里我們要求button并會自動補充空白位置,所有給出0。對于Layout的尺寸大小,重要的是minimumSize()和sizeHint()兩個。如下面。QSize可以通過要求增加某個尺寸大小的文字,它看自動進行調整計算,并需要我們精確計算。最佳大小,我們設置等同于最小尺寸。

QSize FlowLayout::minimumSize() const
{
QSize size;
QLayoutItem * item;
foreach(item,itemList)
size = size. expandedTo (item->minimumSize());
size += QSize(2*margin(),2*margin());
return size;
}

QSize FlowLayout::sizeHint() const
{
return minimumSize();
}

我們補充繼承兩個方法,用于獲取組件之間間隔大小:

int FlowLayout::horizontalSpacing() const
{
if(m_hSpace >= 0)
return m_hSpace;
else
return smartSpacing(QStyle::PM_LayoutHorizontalSpacing /* Default horizontal spacing for a QLayout.*/ );
}

int FlowLayout::verticalSpacing() const
{
if(m_vSpace >= 0 )
return m_vSpace;
else
return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
}

int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const //這是我們定義的private方法,用于從parent中獲得widget之間的間隔
{
QObject * parent = this->parent();
if(!parent){
return -1;
}else if(parent->isWidgetType()){
QWidget * pw = static_cast<QWidget *>(parent);
return pw->style()->pixelMetric(pm,0,pw);
}else{
return static_cast<QLayout*>(parent)->spacing();
}
return 0;
}

進行布局

布局采用setGemetry,這個我們在QT(7)中也介紹過:

void FlowLayout::setGeometry(const QRect & rect)
{
QLayout::setGeometry(rect);
doLayout(rect,false);
}

下面我們根據需求,對doLayout進行說明:

QT(9)自定義layout[2] - Flow Layout

int FlowLayout::doLayout(const QRect & rect, bool testOnly) const
{
int left,top,right,bottom;

getContentsMargins(&left,&top,&right,&bottom);
QRect effectiveRect = rect. adjusted (left,top,-right,-bottom);
int x = effectiveRect.x();
int y = effectiveRect.y();
int lineHeight = 0;

我們第一步,先計算有效的擺放widget的尺寸effectiveRect。

QLayoutItem * item;
foreach(item,itemList){
//It then sets the proper amount of spacing for each widget in the layout, based on the current style.
QWidget * wid = item->widget();
int spaceX = horizontalSpacing();
if(spaceX == -1)
spaceX = wid->style()->layoutSpacing(QSizePolicy::PushButton,QSizePolicy::PushButton,Qt::Horizontal);
int spaceY = verticalSpacing();
if(spaceY == -1)
spaceY = wid->style()->layoutSpacing(QSizePolicy::PushButton,QSizePolicy::PushButton,Qt::Vertical);

在這里,我們獲取一些基本的數據,包括每一個item,其大小為item->sizeHint(),在水平方向各組件之間的間隔spaceX以及豎直方向的間隔spaceY。我們將在effectiveRect內順序排列widget。下面我們來進行計算,設置各個item的setGeometry,需要獲取每個item的起始左上角坐標。

int nextX = x + item->sizeHint().width() + spaceX; //下一個組件的左上角位置的x坐標
if(nextX - spaceX > effectiveRect.right() && lineHeight > 0){ //如果超出位置, 換行 ,重新計算(x,y)坐標
x = effectiveRect.x();
y = y + lineHeight + spaceY;
nextX = x+item->sizeHint().width() + spaceX;
lineHeight = 0;
}
if(!testOnly) //設置item的位置
item-> setGeometry (QRect(QPoint(x,y),item->sizeHint()));
x = nextX;
lineHeight = qMax(lineHeight,item->sizeHint().height());
}

return y + lineHeight - rect.y() + bottom; //返回需要限制所有組件,layout至少要多高
}

對于setGeometry,我們并不需要返回值,但是我們發現,如果組件多,有多行擺放,有時無法全部顯示,這在初始顯示和我們改變window大小的時候可能會出現,而doLayout就返回了layout顯示所有組件時至少需要的height。因此我在width改變是需要重新計算height,需要設置hasHeightForWidth()為true,并heightForWidth返回相應的值。

bool FlowLayout::hasHeightForWidth() const
{
return true;
}

int FlowLayout::heightForWidth(int width) const
{
int height = doLayout(QRect(0,0,width,0),true);
return height;
}

相關鏈接: 我的MeeGo/Moblin相關文章

一個小故事:民國元年的小學國文教科書中有一篇《少年》:一少年在兵營為鼓手,某日,將校會宴,大將勸飲,少年辭曰:吾不嗜酒。大將曰:汝終日擊鼓甚勞,可少飲 酒以舒之。少年固辭不飲,大將不悅。副將在旁,欲試之,厲聲曰:汝必飲一杯,是軍令也,違令將斬汝!少年改容曰:軍令不勝恐懼,然飲酒非兵士職。昔者,吾父以酒疾不起,吾入營時,吾母戒曰:汝終身勿飲酒。雖有大將之命,。不能破慈母之戒。聲淚俱下。坐中將校莫不感動。由是少年益受大將信任,有名于時。

這個故事告訴我們,什么叫做原則,原則不是領導說一句話,就可以搖擺和動搖。現在春節了,在酒桌上該不喝酒就不喝酒,勸酒是一個陋習。當然還有其他很多事情,做一個有良知的人。

QT(9)自定義layout[2] - Flow Layout


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 四虎国产成人免费观看 | 黄在线观看网站 | 久久久久久久国产视频 | 91精品国产综合久久久久久 | 中文字幕专区高清在线观看 | 欧美另类性视频在线看 | 五月天婷婷缴情五月免费观看 | 国产精品资源在线观看 | 天天色综合图片 | 综合久| 久久婷婷是五月综合色狠狠 | a级成人毛片久久 | 久久久噜噜噜久噜久久 | 日本国产亚洲 | 天天操天天射天天操 | 久久精品亚瑟全部免费观看 | 国产精品美女一区二区三区 | 99久久99久久 | 一本一道波多野结衣一区二区 | 亚洲一区二区在线成人 | 女十八毛片 | 欧美一级毛片高清免费观看 | 91视频国产精品 | 自拍中文字幕 | 国产精品免费久久久久影院 | 五月婷婷伊人网 | 成人免费观看视频久爱网 | 久久国产精品免费视频 | 国产精品98福利小视频 | cao美女视频网站在线观看 | 国产精品91在线 | 男女午夜激情 | 亚洲欧洲第一页 | 99re热视频这里只有精品5 | 在线播放亚洲精品富二代91 | 日韩一级欧美一级一级国产 | 亚洲va欧美va | 久久香蕉国产线看观看亚洲片 | 国产精品色 | 国产不卡免费视频 | 青青草a免费线观a |