【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
前面我们用qt编写软件的时候,相关的界面都是通过designer软件来实现的。不过,对于qt来说,它还有一种界面生成的办法,那就是通过编码的方法来生成。虽然编码的方式不一定有designer那么方便,不过在特定场景下面使用还是不错的。比如说,有的时候界面出现的控件数量是不定的,需要由用户自己的参数来进行设定,这种情况下再用designer设计就不合适了。此时,就应该让软件先加载客户的配置设定,再进行界面的渲染。
为了说明如何使用硬编码的方法进行界面开发,我们设计了一个计算器界面来练习下。
1、界面设计的基本方法
其实不仅qt如此,其他图形界面开发平台,一般也会使用grid的设置方法来进行界面布局的。具体来说就是,我们首先把界面分成几行、几列。行的高度、列的宽度都是自己灵活设置的。此外,在每一个grid里面放置多少个控件,也是自己决定的。放置的方法,可以按照垂直方向放置,也可以按照水平方向放置。不仅如此,不同方向的放置,彼此可以嵌套进行的,这就给了使用者很大的方便。当然,如果一个控件比较大,一个grid放不下,需要占用若干行,或者是若干列,这也是可以的。以上就是目前界面设计的基本逻辑和通用框架。
2、创建工程,忽略QtWidgetsApplication文件
首先,我们需要创建一个工程,这部分和之前是一样的。唯一不同的是,我们不再需要用designer设计界面。缺少这一步骤,当然也就不需要对它的头文件、源文件进行增删查改的操作了。
3、编写代码,开始布局
这里涉及的计算器界面比较简单。整个布局采用grid布局的形式。首先第一行是一个QLineEdit编辑器。它的目的是显示当前的输入。接着绘制下半部分,就是16个按钮。这里面包括了0-9十个数字、+-*/四个符号、小数点以及一个=。整体的内容不多,最关键的其实就是等于号,系统需要判断出当前输入是等于号的时候,就要对整个表达式开始计算了。
// header file start here
#include <QApplication>
#include <QWidget>
#include <QGridLayout>
#include <QPushButton>
#include <QLineEdit>
// function declaration
static double calculate(QString str);
// main function start here
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QWidget window;
window.setWindowTitle("Calculator");
window.setFixedWidth(600);
window.setFixedHeight(400);
// create the layout
QGridLayout *layout = new QGridLayout(&window);
// create the display
QLineEdit *display = new QLineEdit();
display->setAlignment(Qt::AlignRight);
display->setReadOnly(true);
display->setFixedHeight(50);
// add the display to the layout
layout->addWidget(display, 0, 0, 1, 4);
// create the buttons
const QStringList buttonsText = {
"7", "8", "9", "-",
"4", "5", "6", "*",
"1", "2", "3", "/",
"0", ".", "+", "="
};
// add the buttons to the layout
for (int i = 0; i < 16; ++i) {
QPushButton *button = new QPushButton(buttonsText[i]);
button->setFixedHeight(40);
layout->addWidget(button, 1 + i / 4, i % 4);
// set up signal-slot connections, and setup anonymous function
if (buttonsText[i] == "=") {
QObject::connect(button, &QPushButton::clicked, [&] {
// evaluate the expression and set the result to the display
QString expression = display->text();
display->setText(QString::number(calculate(expression)));
});
}
else {
QObject::connect(button, &QPushButton::clicked, [=] {
// append the clicked button's text to the display
display->setText(display->text() + button->text());
});
}
}
// show your window here
window.show();
return app.exec();
}
4、表达式的计算
前面我们说过,输入=的话,就要计算整个表达式了。由于作者目前主要是练习qt为主,这方面没有花费很长的时间去了解,所以直接从网上找了一个function来代替实现了。有兴趣的朋友可以直接查看原来的url地址,进一步学习下,代码中有提及url在什么地方,
// transfer the string to the calculated result
//https://blog.csdn.net/be_quiet_endeavor/article/details/78847565
//
static double calculate(QString str)
{
if (str.indexOf("+") != -1)
{
int i = str.indexOf("+");
return calculate(str.left(i)) + calculate(str.right(str.length() - 1 - i));
}
if (str.indexOf("-") != -1)
{
QStringList list = str.split('-');
double value = calculate(list[0]);
if (str.at(0) == "-")
value = -value;
for (int i = 1; i < list.count(); ++i)
{
value -= calculate(list[i]);
}
return value;
}
if (str.indexOf("*") != -1)
{
int i = str.indexOf("*");
return calculate(str.left(i))*calculate(str.right(str.length() - 1 - i));
}
if (str.indexOf("/") != -1)
{
QStringList list = str.split('/');
double value = calculate(list[0]);
for (int i = 1; i < list.count(); ++i)
{
value /= calculate(list[i]);
}
return value;
}
return str.toDouble();
}
5、编译和测试
所有工作都做好之后,就可以开始编译和测试了。我们首先保证编译没有问题。其次等窗口启动之后,通过输入一定的表达式,比如100/2,再输入等于号的时候,确认一下结果是不是50。如果没有问题,那么代表我们的设计是正确的。