Skip to content

Latest commit

 

History

History
434 lines (305 loc) · 10.2 KB

280.md

File metadata and controls

434 lines (305 loc) · 10.2 KB

布局管理

原文: http://zetcode.com/gui/csharpqyoto/layoutmanagement/

在 Qyoto C# 编程教程的这一部分中,我们将介绍布局管理器。

在设计应用的 GUI 时,我们决定要使用哪些组件以及如何在应用中组织这些组件。 为了组织我们的组件,我们使用专门的不可见对象,称为布局管理器。 Qyoto 中有多个选项。 我们可以使用绝对定位,内置布局管理器或创建自定义布局管理器。 我们还可以使用 Qt Designer 直观地构建布局。

Qyoto 有一些重要的内置布局管理器。 QVBoxLayout类垂直排列小部件。 QHBoxLayout水平排列小部件。 QGridLayout类将小部件布置在网格中。 网格布局是最灵活的布局管理器。 框布局可以相互嵌套以创建复杂的布局。

绝对定位

在大多数情况下,程序员应使用布局管理器。 在某些情况下,我们可以使用绝对定位。 在绝对定位中,程序员以像素为单位指定每个小部件的位置和大小。 如果调整窗口大小,则窗口小部件的大小和位置不会改变。 应用在各种平台上看起来都不同,在 Linux 上看起来不错,在 Mac 上看起来不好。 在应用中更改字体可能会破坏布局。 如果将应用翻译成另一种语言,则必须重做布局。 对于所有这些问题,仅在有理由时才使用绝对定位。

using System;
using QtCore;
using QtGui;

/**
 * ZetCode Qyoto C# tutorial
 *
 * In this program, we lay out widgets
 * using absolute positioning
 *
 * @author Jan Bodnar
 * website zetcode.com
 * last modified October 2012
 */

public class QyotoApp : QWidget 
{
    public QyotoApp() 
    {
        WindowTitle = "Absolute";

        InitUI();

        Resize(300, 280);
        Move(300, 300);
        Show();
    }

    void InitUI() 
    {        
        StyleSheet = "QWidget { background-color: #414141 }";

        QPixmap bardejov = new QPixmap("bardejov.jpg");
        QPixmap rotunda = new QPixmap("rotunda.jpg");
        QPixmap mincol = new QPixmap("mincol.jpg");

        QLabel barLabel = new QLabel(this);
        barLabel.Pixmap = bardejov;
        barLabel.Move(20, 20);

        QLabel rotLabel = new QLabel(this);
        rotLabel.Pixmap = rotunda;
        rotLabel.Move(40, 160);

        QLabel minLabel = new QLabel(this);
        minLabel.Pixmap = mincol;
        minLabel.Move(170, 50);
    }

    [STAThread]
    public static int Main(String[] args) 
    {
        new QApplication(args);
        new QyotoApp();
        return QApplication.Exec();
    }
}

在此示例中,我们使用绝对定位显示了三幅图像。

StyleSheet = "QWidget { background-color: #414141 }";

StyleSheet属性用于更改窗口工作区的背景颜色。

QLabel barLabel = new QLabel(this);
barLabel.Pixmap = bardejov;

QLabel小部件用于保存图像。

barLabel.Move(20, 20);

我们使用Move()方法将标签放置在窗口上的x = 20y = 20处。

调整窗口大小时,标签将保留其初始大小。

Absolute

图:绝对定位

按钮示例

在下面的示例中,我们将在窗口的右下角放置两个按钮。

using System;
using QtCore;
using QtGui;

/**
 * ZetCode Qyoto C# tutorial
 *
 * In this program, use box layouts
 * to position two buttons in the
 * bottom right corner of the window.
 *
 * @author Jan Bodnar
 * website zetcode.com
 * last modified October 2012
 */

public class QyotoApp : QWidget 
{
    public QyotoApp() 
    {
        WindowTitle = "Buttons";

        InitUI();

        Resize(300, 150);
        Move(300, 300);
        Show();
    }

    void InitUI() 
    {    
        QVBoxLayout vbox = new QVBoxLayout(this);
        QHBoxLayout hbox = new QHBoxLayout();

        QPushButton ok = new QPushButton("OK", this);
        QPushButton apply = new QPushButton("Apply", this);

        hbox.AddWidget(ok, 1, AlignmentFlag.AlignRight);
        hbox.AddWidget(apply);

        vbox.AddStretch(1);
        vbox.AddLayout(hbox);
    }

    [STAThread]
    public static int Main(String[] args) 
    {
        new QApplication(args);
        new QyotoApp();
        return QApplication.Exec();
    }
}

我们使用嵌套框布局来获得我们想要的布局。

QVBoxLayout vbox = new QVBoxLayout(this);
QHBoxLayout hbox = new QHBoxLayout();

我们使用一个垂直框和一个水平框。

QPushButton ok = new QPushButton("OK", this);
QPushButton apply = new QPushButton("Apply", this);

这是两个将进入窗口右下角的按钮。

hbox.AddWidget(ok, 1, AlignmentFlag.AlignRight);

我们将确定按钮放入水平框中。 第二个参数是stretch因子。 它将扩大分配给“确定”按钮的区域。 它会占用所有可用空间。 在此区域内,按钮向右对齐。

vbox.AddStretch(1);

这条线创建了一个垂直扩展的白色空间,它将带有按钮的水平框推到底部。

vbox.AddLayout(hbox);

水平框嵌套在垂直框中。

Buttons example

图:按钮示例

Windows 示例

以下是嵌套框布局更复杂的示例。

using System;
using QtCore;
using QtGui;

/**
 * ZetCode Qyoto C# tutorial
 *
 * In this program, use box layouts
 * to create a windows example.
 *
 * @author Jan Bodnar
 * website zetcode.com
 * last modified October 2012
 */

public class QyotoApp : QWidget 
{
    public QyotoApp() 
    {
        WindowTitle = "Windows";

        InitUI();

        Resize(350, 300);
        Move(300, 300);
        Show();
    }

    void InitUI() 
    {
        QVBoxLayout vbox = new QVBoxLayout(this);

        QVBoxLayout vbox1 = new QVBoxLayout();
        QHBoxLayout hbox1 = new QHBoxLayout();
        QHBoxLayout hbox2 = new QHBoxLayout();

        QLabel windLabel = new QLabel("Windows", this);
        QTextEdit edit = new QTextEdit(this);
        edit.Enabled = false;

        QPushButton activate = new QPushButton("Activate", this);
        QPushButton close = new QPushButton("Close", this);
        QPushButton help = new QPushButton("Help", this);
        QPushButton ok = new QPushButton("OK", this);

        vbox.AddWidget(windLabel);

        vbox1.AddWidget(activate);
        vbox1.AddWidget(close, 0, AlignmentFlag.AlignTop);
        hbox1.AddWidget(edit);
        hbox1.AddLayout(vbox1);

        vbox.AddLayout(hbox1);

        hbox2.AddWidget(help);
        hbox2.AddStretch(1);
        hbox2.AddWidget(ok);

        vbox.AddLayout(hbox2, 1);

        Layout = vbox;
    }

    [STAThread]
    public static int Main(String[] args) 
    {
        new QApplication(args);
        new QyotoApp();
        return QApplication.Exec();
    }
}

在此布局中,我们使用两个垂直和水平框。

QVBoxLayout vbox = new QVBoxLayout(this);

这是示例的基本布局。

vbox.AddWidget(windLabel);

首先是标签小部件。 它只是转到垂直框的顶部。

vbox1.AddWidget(activate);
vbox1.AddWidget(close, 0, AlignmentFlag.AlignTop);
hbox1.AddWidget(edit);
hbox1.AddLayout(vbox1);

vbox.AddLayout(hbox1);

在窗口的中心部分,我们有一个文本编辑小部件和两个垂直排列的按钮。 这些按钮进入垂直框。 在此垂直框中,按钮与顶部对齐。 垂直框和文本编辑进入水平框。 该水平框转到标签窗口小部件正下方的基本垂直框。

hbox2.AddWidget(help);
hbox2.AddStretch(1);
hbox2.AddWidget(ok);

vbox.AddLayout(hbox2, 1);

帮助和确定按钮进入另一个水平框。 这两个按钮之间有一个扩大的空白区域。 同样,水平框转到基本垂直框。

Layout = vbox;

基本的垂直框设置为窗口的主要布局。

Windows example

图:窗口示例

新文件夹示例

在最后一个示例中,我们使用QGridLayout管理器创建“新文件夹”布局示例。

using System;
using QtCore;
using QtGui;

/**
 * ZetCode Qyoto C# tutorial
 *
 * In this program, use the QGridLayout manager
 * to create a New Folder example.
 *
 * @author Jan Bodnar
 * website zetcode.com
 * last modified October 2012
 */

public class QyotoApp : QWidget 
{
    public QyotoApp() 
    {
        WindowTitle = "New Folder";

        InitUI();

        Resize(300, 300);
        Move(300, 300);
        Show();
    }

    void InitUI() 
    {
        QGridLayout grid = new QGridLayout(this);

        QLabel nameLabel = new QLabel("Name", this);
        QLineEdit nameEdit = new QLineEdit(this);
        QTextEdit text = new QTextEdit(this);
        QPushButton okButton = new QPushButton("OK", this);
        QPushButton closeButton = new QPushButton("Close", this);

        grid.AddWidget(nameLabel, 0, 0);
        grid.AddWidget(nameEdit, 0, 1, 1, 3);
        grid.AddWidget(text, 1, 0, 2, 4);
        grid.SetColumnStretch(1, 1);
        grid.AddWidget(okButton, 4, 2);
        grid.AddWidget(closeButton, 4, 3);
    }

    [STAThread]
    public static int Main(String[] args) 
    {
        new QApplication(args);
        new QyotoApp();
        return QApplication.Exec();
    }
}

在我们的示例中,我们有一个标签,一行编辑,一个文本编辑和两个按钮。

QGridLayout grid = new QGridLayout(this);

我们创建QGridLayout管理器的实例。

grid.AddWidget(nameLabel, 0, 0);

我们将标签小部件放置在网格的第一个单元格中。 单元格从 0 开始计数。最后两个参数是行号和列号。

grid.AddWidget(nameEdit, 0, 1, 1, 3);

线编辑窗口小部件位于第一行第二列。 最后两个参数是行跨度和列跨度。 在水平方向上,小部件将跨越三列。

grid.SetColumnStretch(1, 1);

该方法的参数是列号和拉伸因子。 在这里,我们将拉伸因子 1 设置到第二列。 这意味着此列将占用所有剩余空间。 之所以这样设置,是因为我们希望按钮保持其初始大小。

New Folder example

图:新文件夹 example

在 Qyoto C# 教程的这一部分中,我们提到了小部件的布局管理。