• QT学习:04 代码化的界面绘制


    --- title: framework-cpp-qt-04-代码化的界面绘制 EntryName: framework-cpp-qt-04-ui-design-by-code date: 2020-04-09 15:50:17 categories: tags: - qt - c/c++ ---

    章节描述:

    UI 的可视化设计是对用户而言的,其实底层都是 C++ 的代码实现,只是 Qt 巧妙地进行了处理,让用户省去了很多繁琐的界面设计工作。

    由于Qt界面设计的底层其实都是由 C++ 语言实现的,底层实现的功能比可视化设计更加强大和灵活。

    创建无UI的项目

    某些界面效果是可视化设计无法完成的,或者某些人习惯了用纯代码的方式来设计界面,就可以采用纯代码的方式设计界面,如 Qt 自带的实例基本都是用纯代码方式实现用户界面的。可视化UI设计与代码化UI设计是可以混在一起的。
    采用代码设计实现 UI 时,需要对组件的布局有个完整的规划,不如可视化设计直观,且编写代码工作量大。(建议在代码化设计中,考虑事先使用一些产品文档设计工具进行原型设计)
    可视化UI设计与代码化UI设计是可以混在一起的。但为了做出明显的对比,我们使用无界面的工程作为起点。

    首先建立一个 QT Widgets Appliation 项目 ,填写有关项目信息。

    我这里选择的基类是QWidget,类名为Widget

    不勾选“Generate form”(创建界面)复选框。

    创建后的项目文件目录树下没有 .ui 文件。

    我们的目标是为了创建一个3个单选框,3个选择框,1个编辑框的界面。

    注意:与可视化设计得到的窗体类定义不同,Widget的类定义里没有指向界面的指针 ui

    编写有关代码

    头文件

    在类的头文件widget.h中,做以下步骤:

    添加有关对象

    为了灵活,我们使用指针的形式,等到必要时再实例化。

    #include <QCheckBox>
    #include <QRadioButton>
    
    ...
        
    QCheckBox   	*chkBoxBold;
    QRadioButton    *rBtnBlack;
    

    添加 有关 的 槽

    private slots:
    	void on_chkBoxBold(bool checked); //Bold 的clicked(bool)信号的槽函数
    	void setTextFontColor(); 		  //设置字体颜色
    

    组件初始化

    包括有关UI的创建、以及信号-槽的连接。

    void    iniUI();			//UI 创建与初始化
    void    iniSignalSlots();	//初始化信号与槽的连接
    

    完整的头文件

    // widget.h
    
    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    
    #include <QCheckBox>
    #include <QRadioButton>
    #include <QPlainTextEdit>
    #include <QPushButton>
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    private:
        QCheckBox   	*chkBoxUnder;
        QCheckBox   	*chkBoxItalic;
        QCheckBox   	*chkBoxBold;
        
        QRadioButton    *rBtnBlack;
        QRadioButton    *rBtnRed;
        QRadioButton    *rBtnBlue;
        
        QPlainTextEdit  *txtEdit;
        
        QPushButton     *btnClose;
        
        void    iniUI();//UI 创建与初始化
        void    iniSignalSlots();//初始化信号与槽的链接
        
    private slots:
        void on_chkBoxUnder(bool checked); // Underline 的clicked(bool)信号的槽函数
        void on_chkBoxItalic(bool checked); // Italic 的clicked(bool)信号的槽函数
        void on_chkBoxBold(bool checked);  // Bold 的clicked(bool)信号的槽函数
        void setTextFontColor();  //设置字体颜色    
        
    public:
        Widget(QWidget *parent = nullptr);
        ~Widget();
    };
    #endif // WIDGET_H
    

    源文件

    根据头文件的情况,我们在源文件中给出具体的实现。

    槽函数的实现

    槽函数的功能与界面化设计时类似,只是在访问界面组件时,无需使用 ui 指针,而是直接访问 类里定义的界面组件的成员变量即可。

    void Widget::on_chkBoxUnder(bool checked)
    {
        QFont font=txtEdit->font();
        font.setUnderline(checked);
        txtEdit->setFont(font);
    }
    
    	..
        font.setBold(checked);
    
    	..
        font.setItalic(checked);
    

    界面组件的创建与布局

    控件在布局时可以先不指定父窗口,最后交由Layout统一指定。

    1)创建组件比较简单,只需要new就可以了。

    2)为了布局好看,需要添加一些布局(Layout),再将对应的组件加入布局中。

    3)将布局加入一个"主"布局。

    4)将"主布局"设置为窗体的主布局

    void Widget::iniUI()
    {
        //创建 Underline, Italic, Bold 3 个CheckBox,并水平布局
        chkBoxUnder = new QCheckBox(tr("Underline"));
        chkBoxItalic = new QCheckBox(tr("Italic"));
        chkBoxBold = new QCheckBox(tr("Bold"));
    
        QHBoxLayout *HLay1 = new QHBoxLayout;
    
        HLay1->addWidget(chkBoxUnder);
        HLay1->addWidget(chkBoxItalic);
        HLay1->addWidget(chkBoxBold);
    
        //创建 Black, Red, Blue 3 个RadioButton,并水平布局
        rBtnBlack = new QRadioButton(tr("Black"));
        rBtnBlack->setChecked(true);
        rBtnRed = new QRadioButton(tr("Red"));
        rBtnBlue = new QRadioButton(tr("Blue"));
        QHBoxLayout *HLay2 = new QHBoxLayout;
        HLay2->addWidget(rBtnBlack);
        HLay2->addWidget(rBtnRed);
        HLay2->addWidget(rBtnBlue);
        //创建 退出PushButton, 并水平布局
        btnClose = new QPushButton(tr("Close"));
    
        QHBoxLayout *HLay3 = new QHBoxLayout;
    
        HLay3->addStretch();
        HLay3->addWidget(btnClose);
        //创建文本框,并设置初始字体
        txtEdit = new QPlainTextEdit;
        txtEdit->setPlainText("Hello world
    
    It is my demo");
        QFont font = txtEdit->font(); //获取字体
        font.setPointSize(20);//修改字体大小
        txtEdit->setFont(font);//设置字体
        //创建垂直布局,并设置为主布局
        QVBoxLayout *VLay = new QVBoxLayout;
        VLay->addLayout(HLay1); //添加字体类型组
        VLay->addLayout(HLay2);//添加字体颜色组
        VLay->addWidget(txtEdit);//添加PlainTextEdit
        VLay->addLayout(HLay3);//添加按键组
        setLayout(VLay); //设置为窗体的主布局
    }
    

    关联信号槽

    void Widget::iniSignalSlots()
    {
        //三个颜色 QRadioButton 的clicked()信号与setTextFontColor()槽函数关联
        connect(rBtnBlue,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
        connect(rBtnRed,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
        connect(rBtnBlack,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
        //三个字体设置的 QCheckBox 的clicked(bool)信号与相应的槽函数关联
        connect(chkBoxUnder,SIGNAL(clicked(bool)),
                this,SLOT(on_chkBoxUnder(bool)));
        connect(chkBoxItalic,SIGNAL(clicked(bool)),
                this,SLOT(on_chkBoxItalic(bool)));
        connect(chkBoxBold,SIGNAL(clicked(bool)),
                this,SLOT(on_chkBoxBold(bool)));
        //按钮的信号与窗体的槽函数关联
        connect(btnClose,SIGNAL(clicked()),this,SLOT(close()));
    }
    

    组件初始化

    我们将组件初始化的调用放在构造函数中。

    Widget::Widget(QWidget *parent)
        : QWidget(parent)
    {
        iniUI(); //界面创建与布局
        iniSignalSlots(); //信号与槽的关联
        setWindowTitle("Form created mannually");
    }
    

    完整的源文件

    // widget.cpp
    
    #include <QHBoxLayout>
    #include <QVBoxLayout>
    #include "widget.h"
    
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
    {
        iniUI(); //界面创建与布局
        iniSignalSlots(); //信号与槽的关联
        setWindowTitle("Form created mannually");
    }
    
    Widget::~Widget()
    {
    }
    
    void Widget::on_chkBoxUnder(bool checked)
    {
        QFont font=txtEdit->font();
        font.setUnderline(checked);
        txtEdit->setFont(font);
    }
    
    void Widget::on_chkBoxItalic(bool checked)
    {
        QFont font=txtEdit->font();
        font.setItalic(checked);
        txtEdit->setFont(font);
    }
    
    void Widget::on_chkBoxBold(bool checked)
    {
        QFont font=txtEdit->font();
        font.setBold(checked);
        txtEdit->setFont(font);
    }
    
    void Widget::setTextFontColor() //设置字体颜色
    {
        QPalette plet=txtEdit->palette();
        if (rBtnBlue->isChecked())
            plet.setColor(QPalette::Text,Qt::blue);
        else if (rBtnRed->isChecked())
            plet.setColor(QPalette::Text,Qt::red);
        else if (rBtnBlack->isChecked())
            plet.setColor(QPalette::Text,Qt::black);
        else
            plet.setColor(QPalette::Text,Qt::black);
        txtEdit->setPalette(plet);
    }
    
    
    void Widget::iniUI()
    {
        //创建 Underline, Italic, Bold 3 个CheckBox,并水平布局
        chkBoxUnder = new QCheckBox(tr("Underline"));
        chkBoxItalic = new QCheckBox(tr("Italic"));
        chkBoxBold = new QCheckBox(tr("Bold"));
    
        QHBoxLayout *HLay1 = new QHBoxLayout;
    
        HLay1->addWidget(chkBoxUnder);
        HLay1->addWidget(chkBoxItalic);
        HLay1->addWidget(chkBoxBold);
    
        //创建 Black, Red, Blue 3 个RadioButton,并水平布局
        rBtnBlack = new QRadioButton(tr("Black"));
        rBtnBlack->setChecked(true);
        rBtnRed = new QRadioButton(tr("Red"));
        rBtnBlue = new QRadioButton(tr("Blue"));
        QHBoxLayout *HLay2 = new QHBoxLayout;
        
        HLay2->addWidget(rBtnBlack);
        HLay2->addWidget(rBtnRed);
        HLay2->addWidget(rBtnBlue);
        
        //创建 退出PushButton, 并水平布局
        btnClose = new QPushButton(tr("Close"));
    
        QHBoxLayout *HLay3 = new QHBoxLayout;
    
        HLay3->addStretch();
        HLay3->addWidget(btnClose);
        //创建文本框,并设置初始字体
        txtEdit = new QPlainTextEdit;
        txtEdit->setPlainText("Hello world");
        QFont font = txtEdit->font(); //获取字体
        font.setPointSize(20);//修改字体大小
        txtEdit->setFont(font);//设置字体
        //创建垂直布局,并设置为主布局
        QVBoxLayout *VLay = new QVBoxLayout;
        
        VLay->addLayout(HLay1); //添加字体类型组
        VLay->addLayout(HLay2);//添加字体颜色组
        VLay->addWidget(txtEdit);//添加PlainTextEdit
        VLay->addLayout(HLay3);//添加按键组
        
        setLayout(VLay); //设置为窗体的主布局
    }
    
    void Widget::iniSignalSlots()
    {
        //三个颜色 QRadioButton 的clicked()信号与setTextFontColor()槽函数关联
        connect(rBtnBlue,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
        connect(rBtnRed,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
        connect(rBtnBlack,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
        //三个字体设置的 QCheckBox 的clicked(bool)信号与相应的槽函数关联
        connect(chkBoxUnder,SIGNAL(clicked(bool)),
                this,SLOT(on_chkBoxUnder(bool)));
        connect(chkBoxItalic,SIGNAL(clicked(bool)),
                this,SLOT(on_chkBoxItalic(bool)));
        connect(chkBoxBold,SIGNAL(clicked(bool)),
                this,SLOT(on_chkBoxBold(bool)));
        //按钮的信号与窗体的槽函数关联
        connect(btnClose,SIGNAL(clicked()),this,SLOT(close()));
    }
    
  • 相关阅读:
    SparseArray<E>详解
    Android项目实战(十二):解决OOM的一种偷懒又有效的办法
    浅谈GridLayout(网格布局)
    Android项目实战(十一):moveTaskToBack(boolean ) 方法的使用
    Android Studio 项目代码全部消失--出现原因及解决方法
    Installation failed with message INSTALL_FAILED_UID_CHANGED.--APK安装失败解决方法
    Android项目实战(三十):Fresco加载gif图片并播放
    Android项目实战(十):自定义倒计时的TextView
    坚持一段时间了,达不到原有的目的,就应该放弃了——考研每日总结
    191006
  • 原文地址:https://www.cnblogs.com/schips/p/framework-cpp-qt-04-ui-design-by-code.html
Copyright © 2020-2023  润新知