У меня трудоемкие вычисления, которые зависят от двойного значения.Для этого я создал графический интерфейс, в котором я могу установить значение для вычисления, используя QDoubleSpinBox
.Сигнал двойного вращения QDoubleSpinBox::valueChanged(double)
подключен к слоту, который запускает тяжелые вычисления в новом потоке, используя QtConcurrent::run
.Проблема в том, что когда я добавляю индикатор выполнения, окно двойного вращения автоматически заполняет его содержимое (с добавлением нуля до числа десятичных знаков), когда отображается индикатор выполнения.Мне кажется, это потому, что двойное вращение теряет фокус (т.е. индикатор выполнения - это выбранный виджет).
Мой вопрос:
- Как я могу показать индикатор выполнения и сделать так, чтобы двойное вращающееся поле не заполняло остальные десятичные дроби нулями?
Это видео показывает, как, когда индикатор выполнения не отображается, я могу продолжать редактировать окно двойного вращения, в то время как, когда отображается индикатор выполнения, окно двойного вращения заполняет свою точностьс нулями.Это текущее поведение, а не желаемое.Желаемым является то, что после того, как вычисления выполнены, двойная ячейка не автоматически заполняет свои пустые десятичные разряды нулями.Вот код, используемый для видео (полностью доступно в GitHub ):
Заголовок
class DoubleSpinboxHeavyComputation : public QWidget
{
Q_OBJECT
public:
explicit DoubleSpinboxHeavyComputation(QWidget *parent = nullptr);
~DoubleSpinboxHeavyComputation();
signals:
void computationDone();
void progressSignal(int progress_state);
private slots:
void startHeavyComputationInThread();
void heavyComputation();
private:
Ui::DoubleSpinboxHeavyComputation *ui;
int n_ = 0;
};
Реализация
DoubleSpinboxHeavyComputation::DoubleSpinboxHeavyComputation(QWidget *parent)
: QWidget(parent), ui(new Ui::DoubleSpinboxHeavyComputation)
{
ui->setupUi(this);
connect(ui->doubleSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
&DoubleSpinboxHeavyComputation::startHeavyComputationInThread);
}
DoubleSpinboxHeavyComputation::~DoubleSpinboxHeavyComputation()
{
delete ui;
}
void DoubleSpinboxHeavyComputation::startHeavyComputationInThread()
{
if (ui->checkBox->isChecked())
{
QProgressDialog *progress = new QProgressDialog("Computing", "", 0, 0, this);
progress->setWindowTitle(windowTitle());
progress->setWindowFlags((progress->windowFlags() | Qt::CustomizeWindowHint) &
~Qt::WindowCloseButtonHint); // Hide close button
progress->setWindowModality(Qt::WindowModal);
progress->setCancelButton(nullptr);
progress->setMaximum(1000);
progress->show();
connect(this, &DoubleSpinboxHeavyComputation::progressSignal, progress, &QProgressDialog::setValue);
connect(this, &DoubleSpinboxHeavyComputation::computationDone, progress, &QProgressDialog::close);
connect(this, &DoubleSpinboxHeavyComputation::computationDone, progress, &QProgressDialog::deleteLater);
}
QtConcurrent::run(this, &DoubleSpinboxHeavyComputation::heavyComputation);
}
void DoubleSpinboxHeavyComputation::heavyComputation()
{
int current_n = n_;
++n_;
qDebug() << "Start computation " << current_n;
for (int i = 0; i < 1000; i++)
{
emit progressSignal(i);
usleep(1000);
}
qDebug() << "End computation" << current_n;
emit computationDone();
}