前提・実現したいこと
QTアプリケーション上でUndo/Redoの機能を実装するためにQUndoStack,QUndoCommandクラスを使用し練習を行っています。
試しにChangeボタンを押した際にSpinBoxの数値の値をlineEditに反映するといったアプリケーションを作成し、Undoボタンを押下した際に前の値に戻りRedoボタンを押下した際には後の値に戻るといったプログラムを作成したのですが、私が作成したアプリケーションではUndo/Redoボタンを2回押下しないと値の変更がされないといった不具合が発生しています。
①のスピンボックスで値を変更し③のChangeボタンを押下した際に②のlineEditのスピンボックスで選択した値が変更されるといったプログラムとなっております。
図の状態でUndoボタンを1度押下した際に4の値がlineEditに判明されてほしいのですが、2回押下しないと反映されずRedoする際にも2回押下しないと反映されないといった問題が発生しています。
どうにかして、1回のボタン押下で反映されるように修正したいのですがどうすれば良いのでしょうか。
ご指南頂けると幸甚に存じます。
該当のソースコード
C++
1[main.cpp] 2#include "widget.h" 3#include <QApplication> 4 5#include <QUndoStack> 6int main(int argc, char *argv[]) 7{ 8 QApplication a(argc, argv); 9 QUndoStack *m_undoStack = new QUndoStack; 10 Widget w(m_undoStack); 11 w.show(); 12 13 return a.exec(); 14}
C++
1[Widget.h] 2#ifndef WIDGET_H 3#define WIDGET_H 4 5#include <QWidget> 6#include <QUndoStack> 7#include <QUndoView> 8 9namespace Ui { 10class Widget; 11} 12 13class Widget : public QWidget 14{ 15 Q_OBJECT 16 17public: 18 explicit Widget(QUndoStack *undoStack,QWidget *parent = 0); 19 ~Widget(); 20 21protected: 22 void closeEvent(QCloseEvent *) Q_DECL_OVERRIDE; 23 24public: 25 void onChangeButtonClicked(); 26 void changeDisplay(int value); 27 28public slots: 29 void changeValueSpinBox(int value); 30 31private: 32 Ui::Widget *ui; 33 QUndoStack *m_undoStack; 34 QUndoView *m_undoView; 35 int m_value; 36 QList<int> m_valueList; 37 38}; 39 40#endif // WIDGET_H
C++
1[Widget.cpp] 2#include "widget.h" 3#include "ui_widget.h" 4#include "command.h" 5 6Widget::Widget(QUndoStack *undoStack,QWidget *parent) : 7 QWidget(parent), 8 ui(new Ui::Widget), 9 m_undoStack(undoStack), 10 m_undoView(new QUndoView(m_undoStack)) 11{ 12 ui->setupUi(this); 13 connect(ui->undoButton,&QPushButton::clicked,m_undoStack,&QUndoStack::undo); 14 connect(ui->redoButton,&QPushButton::clicked,m_undoStack,&QUndoStack::redo); 15 connect(ui->changeButton,&QPushButton::clicked,this,&Widget::onChangeButtonClicked); 16 connect(ui->spinBox,SIGNAL(valueChanged(int)),this,SLOT(changeValueSpinBox(int))); 17 18 m_undoView->setWindowFlags(Qt::Dialog); 19 m_undoView->show(); 20 21} 22 23Widget::~Widget() 24{ 25 delete ui; 26} 27 28void Widget::closeEvent(QCloseEvent *) 29{ 30 m_undoView->close(); 31} 32 33void Widget::onChangeButtonClicked() 34{ 35 qInfo("Click"); 36 command *Command = new command(this,m_value,&m_valueList); 37 m_undoStack->push(Command); 38} 39 40void Widget::changeValueSpinBox(int value) 41{ 42 qInfo("Value Change"); 43 m_value = value; 44} 45 46void Widget::changeDisplay(int value) 47{ 48 ui->lineEdit->setText(QString::number(value)); 49}
C++
1[command.h] 2#ifndef COMMAND_H 3#define COMMAND_H 4 5#include <QUndoCommand> 6 7class Widget; 8 9class command : public QUndoCommand 10{ 11public: 12 command(Widget *widget,const int value,QList<int> *valueList,QUndoCommand *parent = 0); 13 14 15public: 16 void undo() Q_DECL_OVERRIDE; 17 void redo() Q_DECL_OVERRIDE; 18 19private: 20 Widget *m_widget; 21 int m_value; 22 QList<int> *m_valueList; 23}; 24 25#endif // COMMAND_H
C++
1[command.cpp] 2#include "command.h" 3#include "widget.h" 4 5command::command(Widget *widget,const int value,QList<int> *valueList,QUndoCommand *parent): 6 QUndoCommand(parent), 7 m_widget(widget), 8 m_value(value), 9 m_valueList(valueList) 10{ 11} 12 13void command::undo() 14{ 15 qInfo("UNDO"); 16 if(m_valueList->isEmpty()) 17 { 18 return; 19 } 20 21 m_widget->changeDisplay(m_valueList->takeLast()); 22} 23 24void command::redo() 25{ 26 qInfo("REDO"); 27 m_valueList->push_back(m_value); 28 setText(QString("Value:%1").arg(m_value)); 29 m_widget->changeDisplay(m_value); 30}
[widget.ui] <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Widget</class> <widget class="QWidget" name="Widget"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>400</width> <height>300</height> </rect> </property> <property name="windowTitle"> <string>Widget</string> </property> <widget class="QPushButton" name="redoButton"> <property name="geometry"> <rect> <x>220</x> <y>120</y> <width>158</width> <height>32</height> </rect> </property> <property name="text"> <string>Redo</string> </property> </widget> <widget class="QPushButton" name="undoButton"> <property name="geometry"> <rect> <x>220</x> <y>60</y> <width>158</width> <height>32</height> </rect> </property> <property name="text"> <string>Undo</string> </property> </widget> <widget class="QLineEdit" name="lineEdit"> <property name="geometry"> <rect> <x>30</x> <y>140</y> <width>113</width> <height>21</height> </rect> </property> </widget> <widget class="QSpinBox" name="spinBox"> <property name="geometry"> <rect> <x>70</x> <y>70</y> <width>48</width> <height>24</height> </rect> </property> </widget> <widget class="QPushButton" name="changeButton"> <property name="geometry"> <rect> <x>230</x> <y>180</y> <width>113</width> <height>32</height> </rect> </property> <property name="text"> <string>Change</string> </property> </widget> </widget> <layoutdefault spacing="6" margin="11"/> <resources/> <connections/> </ui>
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。