用编程语言C++写一个程序,代码需要能在Qt中运行,而且能够实现不同进制之间的相互转换(二进制、八进制、十进制、十六进制,能够保存历史记录(如十进制a转换为二进制b后,能够通过界面功能调取出a和b),在一次转换结束后可以直接进行下一次转换,也可以重新输入一个数进行新的转换(如 十进制的a转换为二进制的b后,可以立刻用b转换成其他进制或者重新输入一个数d转 换为其他进制),记得建立信号与槽并且定义对转换器vtable的引用,代码中不要出现delete
时间: 2023-12-10 08:42:58 浏览: 124
以下是一个简单的实现,使用了Qt中的QLineEdit、QComboBox、QLabel、QPushButton等控件,并通过信号槽机制实现不同进制之间的转换和历史记录的保存。
```cpp
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton>
#include <QtCore/QDebug>
#include <QtCore/QVector>
#include <QtCore/QSettings>
class Converter : public QObject
{
Q_OBJECT
public:
Converter(QObject* parent = nullptr) : QObject(parent) {}
QString convert(const QString& number, int fromBase, int toBase) const
{
bool ok;
int decimal = number.toInt(&ok, fromBase);
if (!ok) {
return "";
}
QString result;
do {
int remainder = decimal % toBase;
if (remainder < 10) {
result.prepend(QString::number(remainder));
} else {
result.prepend(QChar('A' + remainder - 10));
}
decimal /= toBase;
} while (decimal != 0);
return result;
}
QString convert(const QString& number, const QString& fromBase, const QString& toBase) const
{
return convert(number, baseToInt(fromBase), baseToInt(toBase));
}
static QString intToBase(int value, int base)
{
QString result;
do {
int remainder = value % base;
if (remainder < 10) {
result.prepend(QString::number(remainder));
} else {
result.prepend(QChar('A' + remainder - 10));
}
value /= base;
} while (value != 0);
return result;
}
static int baseToInt(const QString& base)
{
if (base == "二进制") {
return 2;
} else if (base == "八进制") {
return 8;
} else if (base == "十进制") {
return 10;
} else if (base == "十六进制") {
return 16;
} else {
return 0;
}
}
signals:
void resultChanged(const QString& result);
};
class ConverterWidget : public QWidget
{
Q_OBJECT
public:
ConverterWidget(QWidget* parent = nullptr) : QWidget(parent)
{
QHBoxLayout* inputLayout = new QHBoxLayout;
inputLayout->addWidget(new QLabel(tr("请输入要转换的数:")));
m_numberEdit = new QLineEdit;
inputLayout->addWidget(m_numberEdit);
m_fromBaseCombo = new QComboBox;
m_fromBaseCombo->addItem("二进制");
m_fromBaseCombo->addItem("八进制");
m_fromBaseCombo->addItem("十进制");
m_fromBaseCombo->addItem("十六进制");
inputLayout->addWidget(m_fromBaseCombo);
inputLayout->addWidget(new QLabel(tr("转换为")));
m_toBaseCombo = new QComboBox;
m_toBaseCombo->addItem("二进制");
m_toBaseCombo->addItem("八进制");
m_toBaseCombo->addItem("十进制");
m_toBaseCombo->addItem("十六进制");
inputLayout->addWidget(m_toBaseCombo);
QHBoxLayout* buttonLayout = new QHBoxLayout;
QPushButton* convertButton = new QPushButton(tr("转换"));
buttonLayout->addWidget(convertButton);
QPushButton* clearButton = new QPushButton(tr("清除"));
buttonLayout->addWidget(clearButton);
QVBoxLayout* mainLayout = new QVBoxLayout;
mainLayout->addLayout(inputLayout);
mainLayout->addLayout(buttonLayout);
m_resultLabel = new QLabel;
mainLayout->addWidget(m_resultLabel);
setLayout(mainLayout);
connect(convertButton, &QPushButton::clicked, this, &ConverterWidget::convert);
connect(clearButton, &QPushButton::clicked, this, &ConverterWidget::clear);
connect(m_numberEdit, &QLineEdit::returnPressed, this, &ConverterWidget::convert);
loadHistory();
}
signals:
void numberChanged(const QString& number);
void fromBaseChanged(const QString& base);
void toBaseChanged(const QString& base);
private slots:
void convert()
{
QString number = m_numberEdit->text().trimmed();
if (number.isEmpty()) {
return;
}
QString fromBase = m_fromBaseCombo->currentText();
QString toBase = m_toBaseCombo->currentText();
QString result = m_converter.convert(number, fromBase, toBase);
if (result.isEmpty()) {
m_resultLabel->setText(tr("无法进行转换!"));
return;
}
m_resultLabel->setText(result);
emit numberChanged(number);
emit fromBaseChanged(fromBase);
emit toBaseChanged(toBase);
m_history.append({ number, fromBase, toBase, result });
saveHistory();
}
void clear()
{
m_numberEdit->clear();
m_resultLabel->clear();
}
private:
void loadHistory()
{
QSettings settings;
int size = settings.beginReadArray("history");
for (int i = 0; i < size; i++) {
settings.setArrayIndex(i);
m_history.append({
settings.value("number").toString(),
settings.value("fromBase").toString(),
settings.value("toBase").toString(),
settings.value("result").toString()
});
}
settings.endArray();
}
void saveHistory()
{
QSettings settings;
settings.beginWriteArray("history");
for (int i = 0; i < qMin(m_history.size(), maxHistory); i++) {
settings.setArrayIndex(i);
settings.setValue("number", m_history[i].number);
settings.setValue("fromBase", m_history[i].fromBase);
settings.setValue("toBase", m_history[i].toBase);
settings.setValue("result", m_history[i].result);
}
settings.endArray();
}
static const int maxHistory = 10;
QLineEdit* m_numberEdit;
QComboBox* m_fromBaseCombo;
QComboBox* m_toBaseCombo;
QLabel* m_resultLabel;
Converter m_converter;
QVector<struct HistoryItem> m_history;
struct HistoryItem {
QString number;
QString fromBase;
QString toBase;
QString result;
};
};
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
ConverterWidget widget;
widget.show();
return app.exec();
}
#include "main.moc"
```
注意事项:
- 程序中使用了QSettings类来保存历史记录,所以在编译时需要链接QtCore模块。
- 程序中没有定义析构函数,因为Qt中的控件会在其父控件被销毁时自动释放,不需要手动调用delete。
- 程序中并没有实现对输入的数字进行检查,例如二进制数只能包含0和1,八进制数只能包含0~7等等。在实际开发中应当对输入进行检查,避免出现意外情况。
- 程序中使用了QVector类来保存历史记录,因为其支持随机访问和动态扩展等特性,比较适合用于保存历史记录。
阅读全文