背景
前面一节介绍了用Qt 设计计算器的界面,这节将总结一下如何让界面可以运行,如何设计计算器的功能部分。将从以下几方面讲述,计算器的文本编辑控件,可以发射字符的按钮,以及负责处理计算和创建UI的计算器类。项目基于VS2019c语言设计计算器,文件结构如下。这里的结构目录只是一个虚拟的目录,实际每个文件存放的位置需要自己规划。
Ui文件编译
.ui是之前设计的界面,程序运行前ui会被编译为.h。编译的路径和编译后头文件的名称可以在项目属性页面Qt User 配置,如下。当然ui头文件也可以自己写,不用Qt ,但这样有点麻烦。
计算器文本编辑控件 .h
上一节已经在界面中引用了类,这个类需要有一些特定的信号与槽函数。具体功能应该有接受并显示按钮的字符,后退按钮,清除按钮,开始执行计算按钮。还需要发送用户输入到计算器类来完成计算,随后接受并显示结果。完成头文件时,需要注意文件名,类名,信号槽函数名称与界面设计时的名称一致。类继承自,如果对象构造函数接收到了一个父控件,这个对象会自动在适当的时候被析构,大家可以去官网学习下Qt的自动内存管理。这里没有分配内存,所以不用写析构函数,使用默认析构即可。这个声明是个宏定义,有了这个声明c语言设计计算器,这个类就可以使用signal/slot。
#ifndef CALCULATORTEXT_H
代码语言:javascript复制 #define CALCULATORTEXT_H
#include
class calculatortext : public QTextEdit {
Q_OBJECT;
public:
calculatortext(QWidget* parent);
public slots:
void input(char);
void showresult(QString);
void back();
void cleartext();
void equal();
signals:
void sendtext(QString);
private:
QString inputtext;
QString resulttext;
QVector checkstack;
};
#endif //CALCULATORTEXT_H
这是cpp文件,函数写的有些笨重,大家如果有更好的方法可以替换掉。equal()槽函数发射了一个信号,这个信号将送往计算器类来处理。
#include "calculatortext.h"
代码语言:javascript复制 calculatortext::calculatortext(QWidget* parent) :
QTextEdit(parent)
{
}
void calculatortext::input(char symbol) {
inputtext = symbol;
setFontPointSize(22);
setTextColor(QColor(0, 0, 255));
setText(inputtext 'n' resulttext);
//setFontPointSize(22);
//setTextColor(QColor(0,0,255));
}
void calculatortext::showresult(QString result) {
resulttext = result;
setText(inputtext 'n' resulttext);
setFontPointSize(22);
setTextColor(QColor(0, 0, 255));
}
void calculatortext::back() {
inputtext = inputtext.remove(inputtext.size() - 1, 1);
setText(inputtext 'n' resulttext);
setFontPointSize(22);
setTextColor(QColor(0, 0, 255));
}
void calculatortext::cleartext() {
inputtext.clear();
resulttext.clear();
setText(QString("0n0"));
setFontPointSize(22);
setTextColor(QColor(0, 0, 255));
}
void calculatortext::equal() {
emit sendtext(inputtext);
可以发射字符的计算器按钮 .h
按钮的功能就很简单了,只需要按下时发射一个字符。把的()信号换绑为新的可以发射字符的信号即可。
#ifndef CALCULATORBUTTON_H
代码语言:javascript复制 #define CALCULATORBUTTON_H
#include
class calculatorbutton : public QPushButton {
Q_OBJECT;
public:
calculatorbutton(QWidget* parent);
public slots:
void sendchar();
signals:
void click(char);
};
cpp文件中需要定义一下构造函数,因为要将的()与()绑定。按钮的中的信号click(char)在界面设计时,已经绑定到了文本框的相应槽函数。
#include "calculatorbutton.h"
代码语言:javascript复制 calculatorbutton::calculatorbutton(QWidget* parent) :QPushButton(parent) {
connect(this, SIGNAL(clicked()), this, SLOT(sendchar()));
}
void calculatorbutton::sendchar() {
char res = this->text().at(0).toLatin1();
emit click(res);
负责运算和现实ui的计算器类 .h
计算器类继承自,构造函数将会渲染设计好的ui。只要定义下计算用户数据的函数,以及发射结果的信号即可。
#ifndef CALCULATOR_H
代码语言:javascript复制 #define CALCULATOR_H
#include
#include "ui_calculatorui.h"
class Calculator : public QMainWindow {
Q_OBJECT;
public:
Calculator(QWidget* parent = nullptr);
public slots:
void calculate(QString);
signals:
void sendresult(QString);
private:
QString inputtext;
QString resulttext;
QVector checkstack;
Ui::MainWindow ui;
这里比较关键的点就是程序如何去调用和渲染UI。头文件引用了编译好的ui文件,随后在私有变量定义了ui类Ui:: ui。在cpp文件中定义构造函数时,只需要执行Ui::的setup函数即可。随后绑定一下和显示器的信号和槽函数,方法如下。函数受限于时间问题,这里没有写。
#include "calculator.h"
代码语言:javascript复制 Calculator::Calculator(QWidget* parent) :QMainWindow(parent) {
ui.setupUi(this);
calculatortext* textedit = this->findChild("textEdit");
connect(this, SIGNAL(sendresult(QString)), textedit, SLOT(showresult(QString)));
connect(textedit, SIGNAL(sendtext(QString)), this, SLOT(calculate(QString)));
}
void Calculator::calculate(QString) {
emit sendresult(QString("success!"));
主程序
主程序如下,每一个qt程序的主程序应该都类似。
#include "calculator.h"
代码语言:javascript复制 #include
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
Calculator w;
w.show();
return app.exec();
至此,小程序已经可以运行。
编译前遇到了无法解析的外部引用,后来发现模块没有导入,如下。
总结
本节介绍了如何去实现自定义的控件,核心运行的计算器类以及不同对象之间利用信号与槽函数进行通讯,体会了如何组织和构建一个qt程序。其中我们不关注算法如何实现,只关注如何使这些代码组织起来,协调运行。至于如何处理用户的输入,随后有时间更新。
本文共 931 个字数,平均阅读时长 ≈ 3分钟