Qt:可视化UI设计

1060 篇文章 307 订阅

1、创建项目&修改组件的对象名字和显示文本内容

创建一个 Widget Application 项目类 QDialog,在创建窗体时选择基类 QDialog,生成的类命名为 QWDialog,并选择生成窗体。

在界面设计时,对需要访问的组件修改其objectName,比如各个按钮,需要读取输入的编辑框,需要显示结果的标签等,以便在程序里区分。对于不需要程序访问的组件则无需修改其 objectName,如用于界面上组
件分组的 GroupBox、Frame、布局等,让 UI 设计器自动命名即可。

  • objectName是窗体上创建的组件的实例名称,必须唯一,因为程序访问组件是通过objectName进行访问的。
  • 窗体的 objectName 就是窗体的类名称,在 UI 设计器里不要修改窗体的 objectName,窗体的实例名称需要在使用窗体的代码里去定义。

2、界面组件布局

2.1、界面组件的层次关系。

使用容器类:如 QgoupBox、QtabWidget、QFrame 等。

例如,将 3 个 CheckBox 组件放置在一个 GroupBox 组件里,该 GroupBox组件就是这 3 个 CheckBox 的容器,移动这个 GroupBox 就会同时移动其中的 3 个 CheckBox:在窗体上放置了2个GroupBox组件,在groupBox1里放置 3 个 CheckBox 组件,在 groupBox2 里放置 3 个 RadioButton 组件

2.2、布局管理

2.2.1、组件面板中的Layouts和Spacers

2.2.2、工具栏:调整设计器进入不同的状态,进行布局设计。

单击需要布局的组件,然后点击布局按钮

  • 在窗体上选中组件时Ctrl可以实现组件多选
  • 选择容器内组件,相当于选择了其内部的所有组件

此时,选中两个groupBox,点击Lay Out Horizontally,实现水平布局

 

3、信号与槽

槽就是一个函数:槽函数可以和一个信号关联,当信号被发射时,关联的槽函数被自动执行。

信号与槽关联是用 QObject::connect()函数实现的,其基本格式是:

QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));

connect()是QObject类的一个静态函数,而QObject是所有Qt类的基类,在实际调用时可以忽略前面的限定符,所以可以直接写为:

connect(sender, SIGNAL(signal()), receiver, SLOT(slot())); 

其中:

  •  sender 是发射信号的对象的名称,
  •  signal()是信号名称。信号可以看做是特殊的函数,需要带括号,有参数时还需要指明参数。
  •  receiver 是接收信号的对象名称
  •  slot()是槽函数的名称,需要带括号,有参数时还需要指明参数。

SIGNAL和STOT是Qt的宏,用于指明信号与槽,并将他们的参数转换为相应的字符串。

(1)一个信号可以连接多个槽,例如:

connect(spinNum, SIGNAL(valueChanged(int)), this, SLOT(addFun(int)); 
connect(spinNum, SIGNAL(valueChanged(int)), this, SLOT(updateStatus(int)); 
  • 这是当一个对象 spinNum 的数值发生变化时,所在窗体有两个槽进行响应,一个 addFun()用于计算,一个 updateStatus()用于更新状态。
  • 当一个信号与多个槽函数关联时,槽函数按照建立连接时的顺序依次执行。
  • 当信号和槽函数带有参数时,在 connect()函数里,要写明参数的类型,但可以不写参数名称。

(2)多个信号可以连接同一个槽

例如在本项目的设计中,让三个选择颜色的 RadioButton的 clicked()信号关联到相同的一个自定义槽函数 setTextFontColor()。

connect(ui->rBtnBlue,SIGNAL(clicked()),this,SLOT(setTextFontColor())); 
connect(ui->rBtnRed,SIGNAL(clicked()),this,SLOT(setTextFontColor())); 
connect(ui->rBtnBlack,SIGNAL(clicked()),this,SLOT(setTextFontColor())); 

这样,当任何一个 RadioButton 被单击时,都会执行 setTextFontColor()函数。

(3)一个信号可以连接另外一个信号

例如:

connect(spinNum, SIGNAL(valueChanged(int)), this, SIGNAL (refreshInfo(int)); 

这样,当一个信号发射时,也会发射另外一个信号,实现某些特殊的功能。


(4)严格的情况下,信号与槽的参数个数和类型需要一致,至少信号的参数不能少于槽的参数。如果不匹配,会出现编译错误或运行错误。
(5)在使用信号与槽的类中,必须在类的定义中加入宏 Q_OBJECT
(6)当一个信号被发射时,与其关联的槽函数通常被立即执行,就像正常调用一个函数一样。
        只有当信号关联的所有槽函数执行完毕后,才会执行发射信号处后面的代码

4 可视化生成槽函数原型和框架

下面开始设计程序功能。对于该程序,希望它的功能如下。

  • 单击 UnderLine、Italic、Bold 3 个 CheckBox 时,根据其状态,设置 PlainTextEdit 里的文字的字体样式;
  • Black、Red、Blue 3 个 RadioButton 是互斥选择的,单击某个 RadioButton 时,设置文字的颜色;
  • 单击“确定”“取消”或“退出”按钮时,关闭窗口,退出程序。

4.1、字体样式设置

选中chkBoxUnder 组件---->“Go to slot…”,出现下面的对话框:列出了QCheckBox类的所有信号,第一个是clicked(),第2个是带bool参数的clicked(bool)

  • 信号clicked():需要在代码中读取CheckBox组件的选中状态
  • 信号号 clicked(bool):将CheckBox组件当前的选择状态作为一个参数传递,在响应代码中可以直接利用这个传递的参数

选择 clicked(bool),然后单击“OK”按钮,在 QWDialog 的类定义中,会在 private slots 部分自动增加一个槽函数声明,函数名是根据发射对象及其信号名称自动命名的。

void on_chkBoxUnder_clicked(bool checked); 

同时,在 qwdialog.cpp 文件中自动添加了函数 on_chkBoxUnder_clicked(bool)的框架。添加代码

void QWDialog::on_chkBoxUnder_clicked(bool checked)
{
    QFont font = ui->txtEdit->font();
    font.setUnderline(checked);
    ui->txtEdit->setFont(font);
}

以同样的方法为 Italic 和 Bold 两个 CheckBox 设计槽函数,编译后运行,发现已经实现了修改字体的下划线、斜体、粗体属性的功能,说明信号与槽函数已经关联了。

QWDialog 的构造函数执行ui->setupUi(this); ------->的 ui_qwdialog.h 中setupUi有:

 QMetaObject::connectSlotsByName(QWDialog);

connectSlotsByName<QWDialog>函数将搜索QWDialog界面上的所有组件,将信号与槽函数的信号和槽关联起来。它假设槽函数的名称是:void on_<object name>_<signal name>(<signal parameters>)

比如,通过UI设计器的操作,为chkBoxUnder自动生成的槽函数是:void QWDialog::on_chkBoxUnder_clicked(bool checked)。那么,connectSlotsByName()就会将此信号和槽函数关联起来,如同执行了下面的这样一条语句:
connect(chkBoxUnder, SIGNAL(clicked (bool)),  this, SLOT (on_chkBoxUnder_clicked (bool)); 

这就是用 UI 设计器可视化设计某个组件的信号响应槽函数,而不用手工去将其关联起来的原因,都是在界面类的构造函数里调用 setupUi()自动完成了关联。

总结:

1、选中组件--->go to slot---->clicked(bool)----->添加代码

2、checkBox可以同时选中

4.2、字体颜色设置

设置字体的 3 个 RadioButton 是互斥性选择的,即一次只有一个 RadioButton 被选中,虽然也可以采用可视化设计的方式设计其 clicked()信号的槽函数,但是这样就需要生成 3 个槽函数。这里可以简化设计,即设计一个槽函数,将 3 个 RadioButton 的 clicked()信号关联到这一个槽函数。为此,在 QWDialog 类的 private slots 部分增加一个槽函数定义如下:

void setTextFontColor();

提示 将鼠标光标移动到这个函数的函数名上面,单击右键,在弹出的快捷菜单中选择“Refactor”→“Add Definition in qwdialog.cpp”,就可以在 qwdialog.cpp 文件中自动为函数 setTextFontColor()生成一个函数框架。

void QWDialog::setTextFontColor()
{
    QPalette Plet = ui->txtEdit->palette();
    if(ui->rBtnBlack->isChecked())
        Plet.setColor(QPalette::Text, Qt::black);
    else if(ui->rBtnBlue->isChecked())
        Plet.setColor(QPalette::Text, Qt::blue);
    else if(ui->rBtnRed->isChecked())
        Plet.setColor(QPalette::Text, Qt::red);
    ui->txtEdit->setPalette(Plet);
}

由于这个槽函数是自定义的,所以不会自动与 RadioButton 的 clicked()事件关联,此时编译后运行程序不会实现改变字体颜色的功能。需要在 QWDialog 的构造函数中手工进行关联,代码如下


QWDialog::QWDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::QWDialog)
{
    ui->setupUi(this);
    connect(ui->rBtnBlack, SIGNAL(clicked()), this, SLOT(setTextFontColor()));
    connect(ui->rBtnBlue, SIGNAL(clicked()), this, SLOT(setTextFontColor()));
    connect(ui->rBtnRed, SIGNAL(clicked()), this, SLOT(setTextFontColor()));
}

总结:1、QWDialog 类的 private slots声明槽函数:void setTextFontColor();点击函数名Refactor生成在qwdialog.cpp生成函数框架,并补全函数。

2、在qwdialog.cpp的构造函数里面手动关联

3、RadioButton为单选框

4.3、按钮功能设置

“确定”表示确认选择并关闭对话框,“取消”表示取消选择并关闭对话框,“退出”则直接关闭对话框。

QWDialog是从QDialog继承而来的,QDialog提供了accept(),erject(),close()等槽函数来表示这三种状态,只需要将按钮的clicked()信号与相应槽函数关联即可。

在 UI 设计器里,单击上方工具栏里的“Edit Signals/Slots”按钮[快捷键为F4,取消为F3],窗体进入信号与槽函数编辑状态。

将鼠标移动到“确定”按钮上方,再按下鼠标左键,移动到窗体的空白区域释放左键,这时出现[确定&窗口]关联对话框

  • 左侧的列表框里显示了 btnOK 的信号,选择 clicked(),右边的列表框里显示了QWDialog 的槽函数,选择 accept(),单击“OK”按钮
  • btnCancel 的 clicked()信号与 QWDialog 的 reject()槽函数关联
  •  btnClose的 clicked()信号与 QWDialog 的 close()槽函数关联。
  • 右侧列表框中没有 close()槽函数,需要勾选下方的“Show signals and slots inherited from QWidget”才会出现 close()函数。

设置完 3 个按钮的信号与槽关联之后,在窗体下方的 Signals 和 Slots 编辑器里也显示了这 3个关联。实际上,可以直接在 Signals 和 Slots 编辑器进行关联设置。现在编译并运行程序,单击这 3 个按钮都会关闭程序。

现在编译并运行程序,单击这 3 个按钮都会关闭程序。

那么,这 3 个按钮的信号与槽函数的关联是在哪里实现的呢?答案在 setupUi()函数里,在setupUi()函数里自动增加了以下 3 行代码:

QObject::connect(btnOK, SIGNAL(clicked()), QWDialog, SLOT(accept()));
QObject::connect(btnCancel, SIGNAL(clicked()), QWDialog, SLOT(reject()));
QObject::connect(btnClose, SIGNAL(clicked()), QWDialog, SLOT(close()));

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值