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中这样写:

cpp 复制代码
#include <QApplication>
#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();
}

显示效果:logo显示正确。

代码说明:

ui_toolbasic.h是前面拖动后自动产生的文件,打开可以看到很多关于布局、绘制的代码:

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

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

main.cpp

cpp 复制代码
#include <QApplication>
//#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();
}

toolbasic.h

cpp 复制代码
#ifndef TOOLBASIC_H
#define TOOLBASIC_H

#include <QDialog>
// 增加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

toolBasic.cpp

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

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

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

cpp 复制代码
#include "toolbasic.h"
#include <QRegularExpressionValidator>
#include <QWidget>


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());
}

使用QDialogButtonBox

效果:

在创建界面时选择:Dialog with Buttons Bottom,起名myDialog。 (不要用这个,会报错)diyDialog。

拖动绘制

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

另外,调整最佳尺寸的按钮会失效,需要手动调整尺寸。(自动的会很小,因为只有两个小组件)

代码

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

cpp 复制代码
#include <QRegularExpressionValidator>
#include <QWidget>
#include <QPushButton>
#include <QDialogButtonBox>
#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());
}

注意 ,如果buttonBox->button这里提示invalid use of incomplete type 'class QPushButton',可能是没有引入<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,然后直接在代码里写:

    cpp 复制代码
    this->setWindowIcon(QIcon("://resources/img/xxx_logo.png"));
相关推荐
若水晴空初如梦10 分钟前
QT聊天项目DAY14
开发语言·qt
Bardb3 小时前
02__C++的基本语法
c++·qt
15942315633 小时前
QT使用WxSQLite3打开加密数据库并查询
数据库·qt·sqlite
派阿喵搞电子9 小时前
在UI界面内修改了对象名,在#include “ui_mainwindow.h“没更新
c++·qt·ubuntu·ui
笨笨马甲13 小时前
Qt Quick模块功能及架构
开发语言·qt
姜君竹15 小时前
QT的工程文件.pro文件
开发语言·c++·qt·系统架构
奇树谦15 小时前
使用VTK还是OpenGL集成到qt程序里哪个好?
开发语言·qt
AAA废品回收站陈师傅18 小时前
68常用控件_QGroupBox的使用
qt
明月醉窗台18 小时前
qt使用笔记二:main.cpp详解
数据库·笔记·qt
沉到海底去吧Go18 小时前
【图片自动识别改名】识别图片中的文字并批量改名的工具,根据文字对图片批量改名,基于QT和腾讯OCR识别的实现方案
数据库·qt·ocr·图片识别自动改名·图片区域识别改名·pdf识别改名