I tried to learn some new things from the answers and here's what I did:
- Used Qt Designer so that in
Config.h
, all member variables and widget positioning are gone - User can't set the lower bound higher than the upper and vice versa
- Replaced obsolete
qrand
with generators from the C++11<random>
library - Used the Qt5 version of
connect
- Better UI with more options
I like code which can be read as plain English text, that's why I made functions such as _removeLastChar
or _correctInputParameters
which are basically one-liners but, for me, improve readability a lot.
Code-review IMHO taught me the most about code quality that is why I am asking this "new" version.
generator.h
#ifndef GENERATOR_H
#define GENERATOR_H
#include <QMainWindow>
class QSpinBox;
namespace Ui {
class Generator;
}
class Generator : public QMainWindow
{
Q_OBJECT
public:
explicit Generator(QWidget *parent = nullptr);
~Generator();
public slots:
void generateNumber();
void clear();
void saveToFile();
void setMinValue(int);
void setMaxValue(int);
private:
Ui::Generator *ui;
qint32 _generateNumber();
QString _getSeparator();
QString _nums;
bool _correctInputParameters();
bool _oneLineOutput();
void _generateNumbers( int from, int to, bool random );
void _removeLastChar( QString& string );
};
#endif // GENERATOR_H
generator.cpp
#include "generator.h"
#include "ui_generator.h"
#include <random>
#include <iostream>
#include <QMessageBox>
#include <QTextStream>
#include <QFileDialog>
Generator::Generator(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::Generator)
{
ui->setupUi(this);
connect(ui->generateButton, &QPushButton::clicked, this, &Generator::generateNumber);
connect(ui->clearButton, &QPushButton::clicked, this, &Generator::clear);
connect(ui->saveButton, &QPushButton::clicked, this, &Generator::saveToFile);
connect(ui->exitButton, &QPushButton::clicked, this, &QApplication::exit);
connect(ui->minimumSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &Generator::setMinValue);
connect(ui->maximumSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &Generator::setMaxValue);
}
void Generator::generateNumber() {
clear();
int numbersCount = ui->numbers->value ();
_nums = "";
// random numbers
if ( ui->random->isChecked () ) {
_generateNumbers (0, numbersCount, true);
}
// sequential numbers
else {
int lower = ui->minimumSpinBox->value ();
int upper = ui->maximumSpinBox->value ();
_generateNumbers (lower, upper + 1, false);
}
ui->textEdit->setText (_nums);
}
void Generator::_generateNumbers( int low, int high, bool random ) {
QString separator = _getSeparator();
for ( qint32 i = low; i < high; ++i ) {
if ( random ) { // random
_nums += QString::number ( _generateNumber () );
}
else { // sequential
_nums += QString::number( i );
}
_nums += separator;
// output into multiple lines
if ( !_oneLineOutput () ) {
_nums += "\n";
}
}
// get rid of the last separator char
if ( _oneLineOutput () && separator != "" ) { _removeLastChar(_nums);}
}
void Generator::saveToFile () {
QString filename = QFileDialog::getSaveFileName (this,
tr("Save numbers"), "",
tr("Text file (*.txt);;All Files(*)"));
if ( filename.isEmpty () ) { return; }
QFile output( filename );
if ( !output.open(QIODevice::WriteOnly | QIODevice::Text) ) {
QMessageBox::information( this,
tr("Unable to open file"),
output.errorString() );
return;
}
QTextStream ts( &output );
ts << _nums.toUtf8 ();
output.close();
}
qint32 Generator::_generateNumber() {
std::random_device rd;
std::default_random_engine eng(rd());
std::uniform_int_distribution< qint32 > distr( ui->minimumSpinBox->value (),
ui->maximumSpinBox->value () );
return distr(eng);
}
QString Generator::_getSeparator() {
auto separator = ui->separator->currentText();
if ( separator == "(space)" ) return " ";
if ( separator == "(nothing)" ) return "";
return separator;
}
void Generator::setMinValue( int newValue ) {
auto maxValue = ui->maximumSpinBox->value ();
if ( newValue > maxValue ) { ui->minimumSpinBox->setValue ( maxValue ); }
}
void Generator::setMaxValue ( int newValue ) {
auto minValue = ui->minimumSpinBox->value ();
if ( newValue < minValue ) { ui->maximumSpinBox->setValue (minValue); }
}
void Generator::clear (){
ui->textEdit->clear ();
}
void Generator::_removeLastChar( QString &string ) {
string.remove ( string.size () - 1, 1 );
}
bool Generator::_correctInputParameters() {
return ui->minimumSpinBox->value () <= ui->maximumSpinBox->value ();
}
bool Generator::_oneLineOutput() {
return ui->oneLine->isChecked ();
}
Generator::~Generator() {
delete ui;
}
.ui
file but it contains ~500 lines so I decided not to. Should I append the.ui
now when there is already the answer? \$\endgroup\$ – sliziky Apr 15 at 11:14