qt界面开发入门以及计算器制作
本文介绍了Qt界面开发的基础知识,重点讲解了如何创建简单UI界面并实现功能交互。主要内容包括: Qt界面设计方法,使用标签和按钮控件 槽机制设计,实现按钮与代码功能的连接 使用QProcess类执行外部程序(如记事本) 计算器项目开发全过程: 新建项目配置 界面布局设计 字体和大小设置 按钮功能实现 提供了完整的代码示例,包括命令行执行器和简易计算器 文章还推荐了Qt安装教程和学习资源,适合Qt初
qt界面开发
这节内容不涉及qt的安装,安装请参考
【保姆级图文教程】最新Windows系统QT下载、安装、入门、配置VS Qt环境,图文详细、内容充实
视频学习请参考【QT快速入门 | 最简单最简洁的QT入门教程 | 嵌入式UI】
本内容也是对视频链接的总结,如有侵权立马删稿。
首先我们的目标是用qt制作一个这样的简易页面。

这个页面设计最关键的几个部分就是,打开UI窗口找到

用这两个标签即可
槽设计,槽设计主要是为了让模块可以链接到代码实现相应的功能。

查找使用函数时,选择帮助按钮。
刚开始你可能看不到索引,得在帮助H中找到索引并添加。
它其实就类似于man 2 的作用。
mainwindow.cpp中输入以下代码,即可制作一个打开窗口。输入notepad即可打开记事本。
QProcess *myProcess = new QProcess(parent);
myProcess->start(program, arguments);
完整代码如下。
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent):
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_commitButton_clicked()
{
// 获取lineedit数据
QString program = ui->cmdlineEdit->text();
// 创建process对象
QProcess *myProcess = new QProcess(this);
myProcess->start(program);
}

实现确定、取消、浏览三功能
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent):
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 连接信号与槽 谁发出信号 发出上面信号 谁处理信号 怎么处理
connect(ui->cmdlineEdit,SIGNAL(returnPressed()),this,SLOT(on_commitButton_clicked()));
connect(ui ->CancelButton,&QPushButton::clicked,this, &MainWindow::on_CancelButton_clicked);
connect(ui ->browseButton,&QPushButton::clicked,[this]()
{
QMessageBox::information(this,"信息","点击浏览");
});
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_commitButton_clicked()
{
// 获取lineedit数据
QString program = ui->cmdlineEdit->text();
// 创建process对象
QProcess *myProcess = new QProcess(this);
myProcess->start(program);
}
void MainWindow::on_CancelButton_clicked()
{
this -> close();
}

说实在的感觉还挺好玩的。
计算器制作
如图所示新建项目
选择第一个
选择qmake

我是直接默认

这里选择的是MinGW

以上默认即可。
页面字体设置
选中之后点击三个点点,设计字体。点大小也就是字体大小。
把最大最小都设置好就可以保证你的框都是统一的。

UI界面中将line Edit和Push Button 都放好。

要是觉得叉叉标识太小了,可以设置

计算器完整代码
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "ui_mainwindow.h"
#include <QMainWindow>
#include <QStack>
#include <QString>
#include <QDebug> // 可选,用于调试
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_oneButton_clicked();
void on_zeroButton_clicked();
void on_threeButton_clicked();
void on_leftButton_clicked();
void on_rightButton_clicked();
void on_fourButton_clicked();
void on_fiveButton_clicked();
void on_sixButton_clicked();
void on_sevenButton_clicked();
void on_eightButton_clicked();
void on_nineButton_clicked();
void on_addButton_clicked();
void on_subButton_clicked();
void on_mulButton_clicked();
void on_divButton_clicked();
void on_equalButton_clicked();
void on_twoButton_clicked();
void on_clearButton_clicked();
void on_delButton_clicked();
private:
Ui::MainWindow *ui;
QString expression;
private:
// 获取运算符优先级
int getPriority(QChar op) {
if (op == '+' || op == '-') return 1;
if (op == '*' || op == '/') return 2;
return 0; // 括号或其他
}
// 判断是否为运算符
bool isOperator(QChar c) {
return c == '+' || c == '-' || c == '*' || c == '/';
}
// 执行计算操作
void calculate(QStack<double> &numStack, QStack<QChar> &opStack) {
if (numStack.size() < 2 || opStack.isEmpty()) return;
double right = numStack.pop();
double left = numStack.pop();
QChar op = opStack.pop();
double result = 0;
switch (op.toLatin1()) {
case '+': result = left + right; break;
case '-': result = left - right; break;
case '*': result = left * right; break;
case '/':
if (qFuzzyIsNull(right))
{ // 处理除以零的情况
ui->mainlineEdit->setText("Error: Division by zero");
numStack.push(0);
return;
} else {
result = left / right;
}
break;
}
numStack.push(result);
}
};
#endif // MAINWINDOW_H
mainwindow.c
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
this -> setMaximumSize(232,322);
this -> setMaximumSize(232,322);
this -> setWindowTitle("计算器");
QFont f("Time New Roman",14);
ui -> mainlineEdit->setFont(f);
// 按钮上放图片
QIcon con("D:\\VScode\\qt\\class_five\\calculator\\tt.jpg");
ui->delButton->setIcon(con);
//改变按钮的背景色
ui->equalButton->setStyleSheet("background:green");
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_zeroButton_clicked()
{
expression += "0";
ui->mainlineEdit->setText(expression);
}
void MainWindow::on_oneButton_clicked()
{
expression += "1";
ui->mainlineEdit->setText(expression);
}
void MainWindow::on_twoButton_clicked()
{
expression += "2";
ui->mainlineEdit->setText(expression);
}
void MainWindow::on_threeButton_clicked()
{
expression += "3";
ui->mainlineEdit->setText(expression);
}
void MainWindow::on_fourButton_clicked()
{
expression += "4";
ui->mainlineEdit->setText(expression);
}
void MainWindow::on_fiveButton_clicked()
{
expression += "5";
ui->mainlineEdit->setText(expression);
}
void MainWindow::on_sixButton_clicked()
{
expression += "6";
ui->mainlineEdit->setText(expression);
}
void MainWindow::on_sevenButton_clicked()
{
expression += "7";
ui->mainlineEdit->setText(expression);
}
void MainWindow::on_eightButton_clicked()
{
expression += "8";
ui->mainlineEdit->setText(expression);
}
void MainWindow::on_nineButton_clicked()
{
expression += "9";
ui->mainlineEdit->setText(expression);
}
void MainWindow::on_addButton_clicked()
{
expression += "+";
ui->mainlineEdit->setText(expression);
}
void MainWindow::on_subButton_clicked()
{
expression += "-";
ui->mainlineEdit->setText(expression);
}
void MainWindow::on_mulButton_clicked()
{
expression += "*";
ui->mainlineEdit->setText(expression);
}
void MainWindow::on_divButton_clicked()
{
expression += "/";
ui->mainlineEdit->setText(expression);
}
void MainWindow::on_equalButton_clicked()
{
if (expression.isEmpty()) {
ui->mainlineEdit->setText("0");
return; //立即结束函数执行
}
QStack<double> numStack; // 数字栈,容器顺序存放
QStack<QChar> opStack; // 运算符栈
int i = 0;
int n = expression.length(); //记录整个字节长度
while (i < n) //逐个读取
{
if (expression[i].isDigit() || expression[i] == '.') //是数字或者小数点
{
// 处理数字(包括小数)
QString numStr;
while (i < n && (expression[i].isDigit() || expression[i] == '.'))
{
numStr.append(expression[i]); // 数字读取,切记碰到运算符会被打断
i++;
}
bool ok;
double num = numStr.toDouble(&ok); // 转换数据格式为double型
if (ok)
{
numStack.push(num); // 存入一次数值
}
} else if (expression[i] == '(')
{
// 左括号直接入栈
opStack.push(expression[i]);
i++;
} else if (expression[i] == ')')
{
// 遇到右括号,计算直到遇到左括号
while (!opStack.isEmpty() && opStack.top() != '(')
{
calculate(numStack, opStack); //没有左括号,直接计算
}
if (!opStack.isEmpty() && opStack.top() == '(')
{
opStack.pop(); // 弹出左括号
}
i++;
} else if (isOperator(expression[i])) // 如果当前字符是运算符
{
// 处理运算符优先级
while (!opStack.isEmpty() && getPriority(opStack.top()) >= getPriority(expression[i]))
{ // 栈顶运算符和当前读取到的运算符的优先级
// 只要栈顶运算符的优先级高于或等于当前运算符,就执行计算
calculate(numStack, opStack);
}
opStack.push(expression[i]);
i++;
} else
{
i++; // 跳过空格等无效字符
}
}
// 处理剩余的运算符
while (!opStack.isEmpty()) {
calculate(numStack, opStack);
}
// 显示结果
if (!numStack.isEmpty()) {
double result = numStack.top();
ui->mainlineEdit->setText(QString::number(result, 'g', 10)); // 使用合适精度
expression = QString::number(result); // 更新表达式,便于继续计算
}
}
void MainWindow::on_leftButton_clicked()
{
expression += "(";
ui->mainlineEdit->setText(expression);
}
void MainWindow::on_rightButton_clicked()
{
expression += ")";
ui->mainlineEdit->setText(expression);
}
void MainWindow::on_clearButton_clicked()
{
expression.clear();
ui->mainlineEdit->clear();
}
void MainWindow::on_delButton_clicked()
{
expression.chop(1);
ui->mainlineEdit->setText(expression);
}
我觉得代码中可能最难理解的部分就是,符号优先级判断了
也就是这一块
else if (isOperator(expression[i])) // 如果当前字符是运算符
{
// 处理运算符优先级
while (!opStack.isEmpty() && getPriority(opStack.top()) >= getPriority(expression[i]))
{ // 栈顶运算符和当前读取到的运算符的优先级
// 只要栈顶运算符的优先级高于或等于当前运算符,就执行计算
calculate(numStack, opStack);
}
opStack.push(expression[i]);
i++;
}
结合例子讲一下,解析表达式 “3 + 5 * 2”
让我们通过一个简单的例子来可视化这个过程。假设表达式是 “3 + 5 * 2”,我们知道正确答案是 3 + (5 * 2) = 13,而不是 (3 + 5) * 2 = 16。
| 当前字符 | 动作 | 数字栈 (numStack) | 运算符栈 (opStack) |
|---|---|---|---|
| 5 | 数字,压入数字栈 | [3, 5] | [+] |
| * | 关键步骤:遇到 * | [3, 5] | [+] |
| 1. 进入 while循环 | 2. 检查条件:!opStack.isEmpty()-> 真 (栈有 +) | 3. 比较优先级:getPriority(‘+’)(1) >= getPriority(‘*’)(2)` -> 假 (1 >= 2 不成立) | 4. 因此,while循环条件不满足,跳出循环 |
| 将 *压入运算符栈 | [3, 5] | [+, *] | 5. 执行 opStack.push(‘*’) |
| 2 | 数字,压入数字栈 | [3, 5, 2] | [+, *] |
| | 表达式读完,开始清理栈 | [3, 5, 2] | [+, *] |
while (!opStack.isEmpty())循环开始,
弹出 *和 5, 2,计算 5 * 2 = 10,结果压栈[3, 10][+]
弹出 +和 3, 10,计算 3 + 10 = 13,结果压栈[13][]
![]() |
![]() |
|---|---|
![]() |
![]() |
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐






所有评论(0)