qt中QHBoxLayout或QVBoxLayout布局內控件的動態生成與顯示


---恢復內容開始---

#qt中QHBoxLayout或QVBoxLayout布局內控件的動態生成與顯示 打個比方,我現在寫個小例子,這個小例子是這樣的,整個界面分為倆個部分,分為上半部分和下半部分,上半部分為5個按鈕,點擊5個按鈕,下半部分分別會動態的出現不同的label顯示內容。(顯示內容為:2017到2018歐冠十六強隊伍)效果如下圖所示:效果如下圖所示: ![點擊“英超”按鈕之后](https://upload-images.jianshu.io/upload_images/14361146-9f1c160e81843ae7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![點擊“西甲”按鈕之后](https://upload-images.jianshu.io/upload_images/14361146-29fa03e674e605f7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![點擊“法甲”按鈕之后](https://upload-images.jianshu.io/upload_images/14361146-390683d70ea5ecf4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![點擊“意甲”按鈕之后](https://upload-images.jianshu.io/upload_images/14361146-32694abd99cc6476.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![點擊“德甲”按鈕之后](https://upload-images.jianshu.io/upload_images/14361146-e3c65840bc3318f5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  這個其實是一個很簡單的例子,我寫這個例子的最重要的目的是讓大家來體會第二列的動態生成的layout,其中的控件是lable。 ## 1.重寫你動態界面中需要存放的控件。  首先呢,最重要的一個實現就是對QLabel類進行一次封裝,當你對這個類進行封裝之后,這個QLabel類才可以重復的去new。 ``` #include "teamnamelabel.h"

TeamNameLabel::TeamNameLabel(QString name)
{
this->setText(name);
this->setFixedSize(70,20);
}

###頭文件
PS:在頭文件的定義中有一個坑需要注意一下,那就是**Q_OBJECT**。這處缺失的話在之后的**qobject_cast**轉換的時候,編譯的時候是會報錯的。這個是其中比較大的一個坑。

ifndef TEAMNAMELABEL_H

define TEAMNAMELABEL_H

include

class TeamNameLabel : public QLabel
{
Q_OBJECT
public:
TeamNameLabel(QString name);
};

endif // TEAMNAMELABEL_H

##2.在主布局文件中相關的實現。
**先直接上代碼再說吧!**

include "mainwindow.h"

include <windows.h>

MainWindow::MainWindow(QWidget *parent)
QMainWindow(parent)
{
this->setFixedSize(500,300);
this->InitUi();
s_PremierLeague<<"曼城";
QString pu = 0x6D66;
s_PremierLeague<<"利物"+ pu;
s_PremierLeague<<"熱刺";
QString qie = 0x5207;
s_PremierLeague<<qie+"爾西";
s_PremierLeague<<"曼聯";
QString de = 0x5FB7;
QString huang = 0x7687;
QString li = 0x91CC;
s_LaLiga<<"皇家馬德" + li;
s_LaLiga<<"巴塞羅那";
s_LaLiga<<"塞維利亞";
s_Liguel<<"巴黎聖日耳曼";
s_SerieA<<"尤文圖斯";
s_SerieA<<"羅馬";
s_Bundesliga<<"拜仁";
}

MainWindow::~MainWindow()
{

}

void MainWindow::InitUi()
{
//注意setlayout在MainWindow中是不起作用的
centerWindow = new QWidget();
this->setCentralWidget(centerWindow);
v = new QVBoxLayout(this);
h_up = new QHBoxLayout(this);
h_down = new QHBoxLayout(this);
m_PremierLeague = new QPushButton(this);
m_PremierLeague->setText("英超");
connect(m_PremierLeague,SIGNAL(clicked(bool)),this,SLOT(clickPremierLeague()));
h_up->addWidget(m_PremierLeague);
m_LaLiga = new QPushButton("西甲",this);
m_Ligue1 = new QPushButton("法甲",this);
m_SerieA = new QPushButton("意甲",this);
m_Bundesliga = new QPushButton("德甲",this);
h_up->addWidget(m_LaLiga);
connect(m_LaLiga,SIGNAL(clicked(bool)),this,SLOT(clickLaLiga()));
h_up->addWidget(m_Ligue1);
connect(m_Ligue1,SIGNAL(clicked(bool)),this,SLOT(clickLigue1()));
h_up->addWidget(m_SerieA);
connect(m_SerieA,SIGNAL(clicked(bool)),this,SLOT(clickSerieA()));
h_up->addWidget(m_Bundesliga);
connect(m_Bundesliga,SIGNAL(clicked(bool)),this,SLOT(clickBundesliga()));
v->addLayout(h_up);
v->addLayout(h_down);
centerWindow->setLayout(v);
}

void MainWindow::DynamicLayout(QStringList name)
{
//判斷此布局內的控件個數
if(h_down->count() > 0)
{
int count = h_down->count();
for(int i = count-1 ; i >= 0 ; i --)
{
QLayoutItem *it = h_down->layout()->takeAt(i);
TeamNameLabel oldHistory = qobject_cast<TeamNameLabel>(it->widget());
if(oldHistory != NULL)
delete oldHistory;
}
}
if(name.size() > 0)
{
for(int i = 0 ; i < name.size() ; i++)
{
TeamNameLabel *team = new TeamNameLabel(name[i]);
h_down->addWidget(team);
}
}
}

void MainWindow::clickPremierLeague()
{
DynamicLayout(s_PremierLeague);
}

void MainWindow::clickLaLiga()
{
DynamicLayout(s_LaLiga);
}

void MainWindow::clickLigue1()
{
DynamicLayout(s_Liguel);
}

void MainWindow::clickSerieA()
{
DynamicLayout(s_SerieA);
}

void MainWindow::clickBundesliga()
{
DynamicLayout(s_Bundesliga);
}

1. 大家可能會對“*QString pu = 0x6D66;s_PremierLeague<<"利物"+ pu;”*,這種類似的操作感到好奇,其實我這個是解決中文亂碼問題的一個辦法,如果各位如果有比這個還好的解決中文亂碼的方法也可以留言展示一撥兒。
2. 其實實現QHBoxLayout布局內控件的動態顯示的核心函數實現就是**DynamicLayout**。這個函數的核心的思路分為倆個部分,第一步就是先將原來布局內已經存在的控件先進行清空,第二步進行動態的控件生成。其中在清空布局內原有的控件時,有一個較大的坑,那就是:
    for(int i = count-1 ; i >= 0 ; i --)
    {
        QLayoutItem *it = h_down->layout()->takeAt(i);
        TeamNameLabel *oldHistory = qobject_cast<TeamNameLabel*>(it->widget());
        if(oldHistory != NULL)
            delete oldHistory;
    }
看到這里很多朋友可能還想不到這能有什么坑,事實上,剛開始的時候,我在寫這個循環的時候,i的取值我是從0開始的,問題就出現在這塊兒了,當你i從0開始取值的時候,在進行最后一次**qobject_cast**轉換的時候就會報錯。這塊兒的話應該和內部實現有關系,沒有時間深入進去看。各位想探究的朋友可以留言討論。
3. 其實我在寫這個小例子的時候還碰到了一個很無腦的錯誤,不過之前一直沒有注意到,那就是:在MainWindow之下setLayout是不起作用的,斷斷續續寫qt也寫了挺長時間了,竟然沒有發現這個錯誤。解決方法就是:
centerWindow = new QWidget();
this->setCentralWidget(centerWindow);
##項目源代碼下載

[點擊下載](https://download.csdn.net/download/qq130106486/10707414)

下載地址:https://download.csdn.net/download/qq130106486/10707414


<p>---恢復內容結束---</p>#qt中QHBoxLayout或QVBoxLayout布局內控件的動態生成與顯示
打個比方,我現在寫個小例子,這個小例子是這樣的,整個界面分為倆個部分,分為上半部分和下半部分,上半部分為5個按鈕,點擊5個按鈕,下半部分分別會動態的出現不同的label顯示內容。(顯示內容為:2017到2018歐冠十六強隊伍)效果如下圖所示:效果如下圖所示:
![點擊“英超”按鈕之后](https://upload-images.jianshu.io/upload_images/14361146-9f1c160e81843ae7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![點擊“西甲”按鈕之后](https://upload-images.jianshu.io/upload_images/14361146-29fa03e674e605f7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![點擊“法甲”按鈕之后](https://upload-images.jianshu.io/upload_images/14361146-390683d70ea5ecf4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![點擊“意甲”按鈕之后](https://upload-images.jianshu.io/upload_images/14361146-32694abd99cc6476.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![點擊“德甲”按鈕之后](https://upload-images.jianshu.io/upload_images/14361146-e3c65840bc3318f5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
&emsp;這個其實是一個很簡單的例子,我寫這個例子的最重要的目的是讓大家來體會第二列的動態生成的layout,其中的控件是lable。
## 1.重寫你動態界面中需要存放的控件。
&emsp;首先呢,最重要的一個實現就是對QLabel類進行一次封裝,當你對這個類進行封裝之后,這個QLabel類才可以重復的去new。

include "teamnamelabel.h"

TeamNameLabel::TeamNameLabel(QString name)
{
this->setText(name);
this->setFixedSize(70,20);
}

###頭文件
PS:在頭文件的定義中有一個坑需要注意一下,那就是**Q_OBJECT**。這處缺失的話在之后的**qobject_cast**轉換的時候,編譯的時候是會報錯的。這個是其中比較大的一個坑。

ifndef TEAMNAMELABEL_H

define TEAMNAMELABEL_H

include

class TeamNameLabel : public QLabel
{
Q_OBJECT
public:
TeamNameLabel(QString name);
};

endif // TEAMNAMELABEL_H

##2.在主布局文件中相關的實現。
**先直接上代碼再說吧!**

include "mainwindow.h"

include <windows.h>

MainWindow::MainWindow(QWidget *parent)
QMainWindow(parent)
{
this->setFixedSize(500,300);
this->InitUi();
s_PremierLeague<<"曼城";
QString pu = 0x6D66;
s_PremierLeague<<"利物"+ pu;
s_PremierLeague<<"熱刺";
QString qie = 0x5207;
s_PremierLeague<<qie+"爾西";
s_PremierLeague<<"曼聯";
QString de = 0x5FB7;
QString huang = 0x7687;
QString li = 0x91CC;
s_LaLiga<<"皇家馬德" + li;
s_LaLiga<<"巴塞羅那";
s_LaLiga<<"塞維利亞";
s_Liguel<<"巴黎聖日耳曼";
s_SerieA<<"尤文圖斯";
s_SerieA<<"羅馬";
s_Bundesliga<<"拜仁";
}

MainWindow::~MainWindow()
{

}

void MainWindow::InitUi()
{
//注意setlayout在MainWindow中是不起作用的
centerWindow = new QWidget();
this->setCentralWidget(centerWindow);
v = new QVBoxLayout(this);
h_up = new QHBoxLayout(this);
h_down = new QHBoxLayout(this);
m_PremierLeague = new QPushButton(this);
m_PremierLeague->setText("英超");
connect(m_PremierLeague,SIGNAL(clicked(bool)),this,SLOT(clickPremierLeague()));
h_up->addWidget(m_PremierLeague);
m_LaLiga = new QPushButton("西甲",this);
m_Ligue1 = new QPushButton("法甲",this);
m_SerieA = new QPushButton("意甲",this);
m_Bundesliga = new QPushButton("德甲",this);
h_up->addWidget(m_LaLiga);
connect(m_LaLiga,SIGNAL(clicked(bool)),this,SLOT(clickLaLiga()));
h_up->addWidget(m_Ligue1);
connect(m_Ligue1,SIGNAL(clicked(bool)),this,SLOT(clickLigue1()));
h_up->addWidget(m_SerieA);
connect(m_SerieA,SIGNAL(clicked(bool)),this,SLOT(clickSerieA()));
h_up->addWidget(m_Bundesliga);
connect(m_Bundesliga,SIGNAL(clicked(bool)),this,SLOT(clickBundesliga()));
v->addLayout(h_up);
v->addLayout(h_down);
centerWindow->setLayout(v);
}

void MainWindow::DynamicLayout(QStringList name)
{
//判斷此布局內的控件個數
if(h_down->count() > 0)
{
int count = h_down->count();
for(int i = count-1 ; i >= 0 ; i --)
{
QLayoutItem *it = h_down->layout()->takeAt(i);
TeamNameLabel oldHistory = qobject_cast<TeamNameLabel>(it->widget());
if(oldHistory != NULL)
delete oldHistory;
}
}
if(name.size() > 0)
{
for(int i = 0 ; i < name.size() ; i++)
{
TeamNameLabel *team = new TeamNameLabel(name[i]);
h_down->addWidget(team);
}
}
}

void MainWindow::clickPremierLeague()
{
DynamicLayout(s_PremierLeague);
}

void MainWindow::clickLaLiga()
{
DynamicLayout(s_LaLiga);
}

void MainWindow::clickLigue1()
{
DynamicLayout(s_Liguel);
}

void MainWindow::clickSerieA()
{
DynamicLayout(s_SerieA);
}

void MainWindow::clickBundesliga()
{
DynamicLayout(s_Bundesliga);
}

1. 大家可能會對“*QString pu = 0x6D66;s_PremierLeague<<"利物"+ pu;”*,這種類似的操作感到好奇,其實我這個是解決中文亂碼問題的一個辦法,如果各位如果有比這個還好的解決中文亂碼的方法也可以留言展示一撥兒。
2. 其實實現QHBoxLayout布局內控件的動態顯示的核心函數實現就是**DynamicLayout**。這個函數的核心的思路分為倆個部分,第一步就是先將原來布局內已經存在的控件先進行清空,第二步進行動態的控件生成。其中在清空布局內原有的控件時,有一個較大的坑,那就是:
    for(int i = count-1 ; i >= 0 ; i --)
    {
        QLayoutItem *it = h_down->layout()->takeAt(i);
        TeamNameLabel *oldHistory = qobject_cast<TeamNameLabel*>(it->widget());
        if(oldHistory != NULL)
            delete oldHistory;
    }
看到這里很多朋友可能還想不到這能有什么坑,事實上,剛開始的時候,我在寫這個循環的時候,i的取值我是從0開始的,問題就出現在這塊兒了,當你i從0開始取值的時候,在進行最后一次**qobject_cast**轉換的時候就會報錯。這塊兒的話應該和內部實現有關系,沒有時間深入進去看。各位想探究的朋友可以留言討論。
3. 其實我在寫這個小例子的時候還碰到了一個很無腦的錯誤,不過之前一直沒有注意到,那就是:在MainWindow之下setLayout是不起作用的,斷斷續續寫qt也寫了挺長時間了,竟然沒有發現這個錯誤。解決方法就是:
centerWindow = new QWidget();
this->setCentralWidget(centerWindow);
##項目源代碼下載

[點擊下載](https://download.csdn.net/download/qq130106486/10707414)

下載地址:https://download.csdn.net/download/qq130106486/10707414


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM