关闭

QT(8)变动布局Dynamic Layout

标签: qtlayoutdialogsignalbutton教育
5984人阅读 评论(2) 收藏 举报
分类:

这次,我们学习下面几个问题:

  1. 动态变更布局
  2. QQueue的使用
  3. 组件之间的联动

参考来源:http://doc.qt.nokia.com/latest/layouts-dynamiclayouts.html,最终布局如图所示,并实现相关的动态变更。

  1. 一个dialog分为三个部分;
  2. 第一部分是一个GroupBox,里面是GridLayout(2,2)的方式,按Rotate Widget的按钮,顺时针旋转里面组件的位置。这四个组件是可以联动的,一个修改,另外三个显示值也跟随修改。此四个组件存放在QQueue中。
  3. 第二部分也是一个GroupBox,根据comboBox的选择,确定第三部分的位置。
  4. 第三部分是DialogButtonBox,有两个Dialog的button,close和help,增加一个旋转按钮“Rotate Widget”

 

一、创建程序主体,采用dialog的方式。在之前,我们讨论过dialog的主体如何创建,不再重复。MyDialog类继承QDialog。

二、旋转第一部分的四个组件

在mydialog.h:
private:
    /* 第一部分的组件*/
    QGroupBox *rotableGroupBox;
    QQueue<QWidget *> rotableWidgets;
    QGridLayout *rotableLayout;

在mydialog.cpp:
void MyDialog :: createRotableGroupBox()
{
    rotableGroupBox = new QGroupBox(tr("Rotable Widgets"));
    rotableWidgets.enqueue(new QSpinBox);
    rotableWidgets.enqueue(new QSlider);
    rotableWidgets.enqueue(new QDial);
    rotableWidgets.enqueue(new QProgressBar);
    int n = rotableWidgets.count();

    /*这里设置联动,注意以前第三个参数我们通常使用this,表示调用当前类的函数,对于联动,我们需要调用其他组件的函数,所以这里为其他组件,第一动,导致第二动,第二动,导致第三动,一直所有的都改变,否则一直传递下去*/
    for (int i = 0; i < n; ++i) {
        connect(rotableWidgets[i], SIGNAL(valueChanged(int)), rotableWidgets[(i+1)%n], SLOT(setValue(int)));
    }

    rotableLayout = new QGridLayout;
    rotableGroupBox ->setLayout(rotableLayout);
    rotateWidgets();

}

void MyDialog :: rotateWidgets() //这也同时是slot函数
{
    //删除面板上的组件
    foreach(QWidget * widget ,rotableWidgets)
          rotableLayout->removeWidget(widget);
   //删除head的的item,并将其加到最后,这样我们实现旋转。
    rotableWidgets.enqueue(rotableWidgets.dequeue());
    rotableLayout->addWidget(rotableWidgets[0],1,0);
    rotableLayout->addWidget(rotableWidgets[1],1,1);
    rotableLayout->addWidget(rotableWidgets[2],0,1);
    rotableLayout->addWidget(rotableWidgets[3],0,0);

}

三、横向/纵向模式,自从iphone引入了重量感应器后,一个程序出现横向和纵向的排版,通常都是一样,但是有些程序也提供不同的布局。这里给了一个例子。

在mydialog.h:
private:
    /* 第二部分的组件*/
    QGroupBox *optionsGroupBox;
    QGridLayout *optionsLayout;
    QLabel *buttonsOrientationLabel;
    QComboBox *buttonsOrientationComboBox;
    /* 第三部分的组件*/
    QDialogButtonBox *buttonBox;
    QPushButton *closeButton;
    QPushButton *helpButton;
    QPushButton *rotateWidgetsButton;

在mydialog.cpp:
void MyDialog :: buttonsOrientationChanged(int index)
{
    //由于我们改变排版,因此新的布局的size可能比原来的小,但是widget的resize比它最小的widget大小。通过setMinmumSize(0,0)来reset。简单来讲,如果我们每次修改布局都希望不受限制设定新的尺寸,reset最小尺寸。
    setMinimumSize(0,0);

    //方向有两个参数Qt::Horizontal 0x1, Qt::Vertical 0x2,在我们这里0为Horizontal,1为vertical。
    Qt::Orientation orientation = Qt::Orientation(index + 1);
    if(buttonBox->orientation() == orientation ) //方向没有改变
        return;
 

    mainLayout->removeWidget(buttonBox); //删除原来的buttonBox,后面在其他位置加上

    int spacing = mainLayout->spacing();
    QSize oldSizeHint = buttonBox->sizeHint() + QSize(spacing,spacing);
    buttonBox->setOrientation(orientation);
    QSize newSizeHint = buttonBox->sizeHint() + QSize(spacing,spacing);

    if(orientation == Qt::Horizontal){
        mainLayout->addWidget(buttonBox,2,0); //新的位置,放置最下面
        resize(size() + QSize(-oldSizeHint.width(), newSizeHint.height())); //设置合适的大小
    }else{
        mainLayout->addWidget(buttonBox,0,3,2,1); //新的位置,放置最右面
        resize(size() + QSize(newSizeHint.width(), -oldSizeHint.height())); //设置合适的大小
        //resize(minimumSize().width(), minimumSize().height()); 这样可以得到最紧凑的排列,但是我们希望其他部分不变动,所以我们根据计算进行排版。
    }
}

四、对于第二部分:第二部分只有两个组件,占空间比较小,当我们将dialog拉框的时候,我们希望这两个组件都放置在最左边,右边以空白补充。如下,我们在GruiLayout中增加一个空白类。

//这里设置延伸的情况,我们希望后面空白将填满剩余的空间,所以设置第2列具有更高的延伸因子,如果我们希望第1列的combobox将填满剩余的俄空间,setColumnStretch(1,1),可以拉常dialog来看看效果。
optionsLayout->setColumnStretch(2,1);

五、Dialog的提供的缺省button。使用QDialogButtonBox * buttonBox,在里面我们加入两个系统button,Close和Help,以及一个自定义的button,如下

closeButton = buttonBox->addButton(QDialogButtonBox::Close);
helpButton =  buttonBox -> addButton(QDialogButtonBox::Help);
rotateWidgetsButton = buttonBox->addButton(tr("Rotate &Widget"),QDialogButtonBox::ActionRole);
connect(rotateWidgetsButton,SIGNAL(clicked()),this,SLOT(rotateWidgets()));
connect(closeButton,SIGNAL(clicked()),this,SLOT(close())); //close是系统的,即继承QDialog
connect(helpButton,SIGNAL(clicked()),this,SLOT(myhelp())); //myhelp是自定的

一些思考:点解中国的中小学生学着全世界最复杂的数理化,而我们的大学毕业生的素质如此低下?这个问题曾经很奇怪。实际上看看中小学的教育就知道。填鸭式的教育,目的是教会知识。而不是教会如何学习知识,更不是如何享受学习的乐趣。如果只是知识,在网上查查就可以,而如何学习知识,是人的学习能力,如何独立思考,是人的创新能力。不学会质疑,如何学会创新?

相关链接:我的MeeGo/Moblin相关文章

0
0
查看评论

Android 之 TextView内部如何绘制Span样式

1 Span用处:可以修改TextView中的部分文字的字体,如加粗、下划线、修改颜色、行对齐方式、首行缩进、插入图片等等。具体 android.text.style.* 中寻找自己想要的Span。 之 TextView内部如何绘制Span样式" name="image...
  • bigjeffwind
  • bigjeffwind
  • 2013-02-25 10:51
  • 3912

QT动态布局类的实现

  • 2011-08-30 09:57
  • 3KB
  • 下载

Qt中的动态布局(Dynamic Layout)

Qt中的动态布局 Dynamic Layout 一、QGroupBox组合框中添加控件 二、动态布局
  • u011125673
  • u011125673
  • 2016-07-25 16:42
  • 3163

Qt之水平/垂直布局(QBoxLayout、QHBoxLayout、QVBoxLayout)

简述水平布局,在水平方向上排列控件,即:左右排列。水平布局(QHBoxLayout)、垂直布局(QVBoxLayout)均继承自QBoxLayout,通过查看源码,我们可以发现,水平布局、垂直布局除了构造时的方向(LeftToRight、TopToBottom)不同外,其它均相同。简述 使用 效果 ...
  • u011012932
  • u011012932
  • 2016-05-30 13:28
  • 25535

QLayout 动态布局(如何清空布局)

例子就是qtdemo里面的动态布局的例子,详细代码就不具体列出了,这里主要讲下如何清空布局,以及遇到的问题及其解决办法。 核心代码:  void Dialog::rotateWidgets()  {      Q_ASSERT(rotable...
  • styyzxjq2009
  • styyzxjq2009
  • 2013-02-16 17:18
  • 8178

qt 动态布局的例子,dynamic layout

 动态布局的例子,dynamic layout;包括滑块,进度条。刻度盘,旋转框等子控件。  //**************************************************************#include  #include ...
  • yuanlulu
  • yuanlulu
  • 2009-12-01 11:08
  • 4522

QT实现竖直方向的窗口布局(使用QLayout类)

在QT中使用布局器QLayout进行布局 1.它会为我们自动的计算各个控件的大小和位置; 2.当父窗口调整时,它会根据既定策略Policy来调整各个子窗口的大小和位置。 常用的两个QLayout类属于QBoxLayout中分别为QHLayout和QVlayout类 举个例子:创建两个叠加的纵...
  • baidu_36669549
  • baidu_36669549
  • 2017-07-18 08:28
  • 357

【Qt5开发及实例】6、布局管理之基本布局

给个目标实现以下: 代码展示, 首先创建一个项目,不要界面,选择基类是QDialog这个,后面名字的话随便改改 我的类名是:UserInfo 头文件dialog.h: #ifndef DIALOG_H #define DIALOG_H #include #i...
  • cutter_point
  • cutter_point
  • 2014-12-22 20:05
  • 1956

Qt之表单布局(QFormLayout)

简述QFormLayout管理输入型控件和关联的标签组成的那些Form表单。QFormLayout是一个方便的布局类,其中的控件以两列的形式被布局在表单中。左列包括标签,右列包含输入控件,例如:QLineEdit、QSpinBox等。简述 使用 常用接口 总结 使用我们可以通过addRow(cons...
  • u011012932
  • u011012932
  • 2016-05-30 17:06
  • 13054

QT&nbsp;layout布局子部分大小问题

最近做phonon和普通widget相互融合的时候,试验出来的。 1. 当我用 layout->addWidget(1); layout->addWidget(2);  // or         ...
  • micklf
  • micklf
  • 2015-10-31 11:13
  • 434
    个人资料
    • 访问:4908365次
    • 积分:55333
    • 等级:
    • 排名:第59名
    • 原创:783篇
    • 转载:23篇
    • 译文:237篇
    • 评论:1535条
    博客专栏
    我的公告
    我思故我在,如果一个人无法独立思考,即使熟习各种工具,实质只是工具的一部分,永远无法创造工具。
    文章转载只能用于非商业性质,且不能带有虚拟货币、积分等附加条件;转载必须注明出处。

    我的微博帐号:@恺风Wei
    文章存档