• qt5-入门-使用拖动方式创建Dialog


    参考:
    C++ GUI Programming with Qt 4, Second Edition

    本地环境:
    win10专业版,64位,Qt5.12


    实现效果

    打码的是logo。
    在这里插入图片描述

    基本流程

    创建dialog的流程:

    1. 创建和初始化子部件;
    2. 把子部件放进布局中;
    3. 设置tab顺序;
    4. 连接信号和槽;
    5. 实现自定义的槽。

    逐步实操

    现在一步一步操作:

    **注意:**我一开始是用Qt Creator的设计页面做的,所以截图都是设计页面,但是Qt Creator没有预览,稍微有点不方便,因此第三步我换到Qt Designer了,操作是一样的。

    1)创建和初始化子部件

    先新建一个dialog。
    在这里插入图片描述
    然后打开设计页面,放置几个小组件,如下图所示。不要在意对齐,后面会使用自动对齐:
    在这里插入图片描述
    各个对象的名称和所属的类如下图所示:
    在这里插入图片描述
    需要修改的属性有:

    • 左侧是okButton,修改text为OK,设置enable为false,设置default为true。default表示按回车会触发。
    • 右侧是cancelButton,需改text为cancel

    然后需要设置label的buddy是lineEdit。

    点击菜单栏-编辑-Edit buddies,然后左键点击label,出现箭头后拖动,连接到lineEdit上,如下图所示。
    在这里插入图片描述
    这样buddy就设置成功了。点击编辑菜单栏返回,也可以点击上方的工具条:
    在这里插入图片描述

    2)把子部件放进布局中

    按住ctrl,然后依次选择label和lineEdit,单击工具条上的水平布局,此时布局成功:
    在这里插入图片描述
    然后对spacer和两个按钮做水平布局。随后,反选,单击垂直布局:
    在这里插入图片描述
    现在变成:
    在这里插入图片描述
    可以看到,窗口大小似乎偏大,点击工具条上的调整大小按钮,变成了最优尺寸:
    在这里插入图片描述

    3)设置tab顺序

    设置tab顺序就是部件接受焦点(focus)的顺序,点击的是工具条上带数字的灰色按钮:
    在这里插入图片描述
    因为想要预览效果,我用Qt Designer打开了文件。

    点击窗体-预览,可以看到各种风格下的效果。
    在这里插入图片描述
    windowsvista风格:
    在这里插入图片描述

    windows风格
    在这里插入图片描述

    fushion风格
    在这里插入图片描述
    那么如何套用这个格式呢?

    在main.cpp中这样写:

    #include 
    #include "ui_toolbasic.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        Ui::toolBasic ui;
        QDialog *dialog = new QDialog;
        ui.setupUi(dialog);
        dialog->show();
    
        return a.exec();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    显示效果:logo显示正确。
    在这里插入图片描述
    代码说明:
    ui_toolbasic.h是前面拖动后自动产生的文件,打开可以看到很多关于布局、绘制的代码:
    在这里插入图片描述

    4)连接信号和槽 5)实现自定义的槽

    要实现的效果:限制lineEdit的输入格式,要求以字母开始,后跟一个数字,再跟0-2个数字。只有满足要求时,OK按钮才生效。
    在这里插入图片描述

    main.cpp

    
    #include 
    //#include "ui_toolbasic.h"
    #include "toolbasic.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        
        toolBasic* tb = new toolBasic;
        tb->show();
    
        return a.exec();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    toolbasic.h

    #ifndef TOOLBASIC_H
    #define TOOLBASIC_H
    
    #include 
    // 增加ui这一行,第一步生成form时是没有的
    #include "ui_toolbasic.h"
    
    namespace Ui {
    class toolBasic;
    }
    
    // 声明
    class QWidget;
    
    class toolBasic : public QDialog, public Ui::toolBasic
    {
        Q_OBJECT
    
    public:
        //explicit toolBasic(QWidget *parent = nullptr);
        // 注释掉自动生成的构造函数,重写一个
        toolBasic(QWidget *parent = 0);
        ~toolBasic();
    
    private:
        Ui::toolBasic *ui;
    // 新增槽函数
    private slots:
        void on_lineEdit_textChanged();
    
    };
    
    #endif // TOOLBASIC_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    toolBasic.cpp
    需要注意的是, setupUi()会自动连接一些槽函数,只要槽函数满足格式:on_objectName_signalName(),也就是会蒋objectNamesignalName()连接起来,不用另外写。

    因此,上面新增了槽函数on_lineEdit_textChanged()等于执行到setupUi()时,自动实现了这个连接:
    connect(lineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(on_lineEdit_textChanged()));

    所以只需要实现这个槽函数,就能实现lineEdit内容改变后的自动处理过程。

    #include "toolbasic.h"
    #include 
    #include 
    
    
    toolBasic::toolBasic(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::toolBasic)
    {
        // setupUi()会自动连接一些槽函数,只要槽函数满足格式:on_objectName_signalName()
        setupUi(this);
        // 要求:以字母开头,后跟一个数字(1-9),然后跟0-2个数字(0-9)
        QRegularExpression regExp("[A-Za-z][1-9][0-9]{0,2}");
        lineEdit->setValidator(new QRegularExpressionValidator(regExp, this));
    	// 把okButton连到QDialog::accept()槽函数. 
    	// accept()关闭对话框,但是设置dialog的结果是QDialog::Accepted,也就是1
        connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
        // 把cancelButton连到QDialog::reject()
        // reject()也关闭对话框,但是设置结果为QDialog::Rejected,也就是0
        connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
    
    }
    
    toolBasic::~toolBasic()
    {
        delete ui;
    }
    
    void toolBasic::on_lineEdit_textChanged() {
        // lineEdit有合法输入时,开启ok按钮
        okButton->setEnabled(lineEdit->hasAcceptableInput());
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    使用QDialogButtonBox

    效果:
    在这里插入图片描述
    在创建界面时选择:Dialog with Buttons Bottom,起名myDialog。 (不要用这个,会报错)diyDialog。

    拖动绘制

    与前面相似,就是两个button变成了一个buttonBox。如果需要特殊一点的对齐,需要把预先出现在面板上的buttonBox删掉,不然spacer是放不好的。如果不删的话,上面两个connect也是自动实现了的,不用写。

    另外,调整最佳尺寸的按钮会失效,需要手动调整尺寸。(自动的会很小,因为只有两个小组件)
    在这里插入图片描述

    代码

    diydialog.h和main.cpp跟前面类似,不再重复。diydialog.cpp需要做一点修改:

    #include 
    #include 
    #include 
    #include 
    #include "diydialog.h"
    
    diyDialog::diyDialog(QWidget *parent) :
        QDialog(parent)
    {
        setupUi(this);
        QRegularExpression regExp("[A-Za-z][1-9][0-9]{0,2}");
        lineEdit->setValidator(new QRegularExpressionValidator(regExp, this));
    	// 这里需要修改
        connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
        connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
    }
    
    diyDialog::~diyDialog()
    {
        delete ui;
    }
    
    void diyDialog::on_lineEdit_textChanged(){
    	// 修改
        buttonBox->button(QDialogButtonBox::Ok)->setEnabled(
                    lineEdit->hasAcceptableInput());
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    注意,如果buttonBox->button这里提示invalid use of incomplete type 'class QPushButton',可能是没有引入的原因,include上就解决了。
    在这里插入图片描述

    排错

    设置了windowIcon但不显示

    可能有问题的地方:

    1. 前缀写错

    2. 使用了错误的文件格式
      icon不支持ico格式,换成jpg或者png即可。

    3. 使用拖动方式,在designer中设置icon时,要选选择资源,不要选选择文件!!
      在这里插入图片描述

    4. 图片文件的路径写错
      在这篇文章里qt5-入门-信号槽理解+QMainWindow,我的路径是这样写的:openAction->setIcon(QIcon(":/pic.jpg"));,但是我现在把文件放到专门的文件夹下了,文件结构如下图:
      在这里插入图片描述
      如果直接写:/resources/img/xxx_logo.png,其实是访问不到的。更简单的方法是editor中查看res.qrc,右键复制path,可以看到复制结果是:://resources/img/xxx_logo.png,然后直接在代码里写:

      this->setWindowIcon(QIcon("://resources/img/xxx_logo.png"));
      
      • 1

      在这里插入图片描述

  • 相关阅读:
    泛型类的认识 - (了解数据结构的基础)
    计算机竞赛 基于深度学习的视频多目标跟踪实现
    景联文科技:数据供应商在新一轮AI热潮中的重要性
    华为认证 | 这门HCIA认证正式发布!
    为啥强烈禁止使用Calendar?
    【函数式编程实战】(四)流-Stream API原理解析
    uni-app ——商品规格多选择以及收货地址的实现思路详解
    线程池拒绝策略最佳实践
    Docker:本地目录挂载
    Kafka Stream 学习笔记-3 DSL‘s stateless stateful
  • 原文地址:https://blog.csdn.net/pxy7896/article/details/136375521