当前位置:   article > 正文

嵌入式Qt 实现用户界面与业务逻辑分离_qt 界面与操作逻辑怎么分离

qt 界面与操作逻辑怎么分离

一.基本程序框架一般包含

二.框架的基本设计原则

三.用户界面与业务逻辑的交互

 

 四.代码实现计算器用户界面与业务逻辑

ICalculator.h

  1. #ifndef _ICALCULATOR_H_
  2. #define _ICALCULATOR_H_
  3. #include <QString>
  4. class ICalculator
  5. {
  6. public:
  7. virtual bool expression(const QString& exp) = 0;
  8. virtual QString result() = 0;
  9. };
  10. #endif

QCalculator.h

  1. #ifndef _QCALCULATOR_H_
  2. #define _QCALCULATOR_H_
  3. #include "QCalculatorUI.h"
  4. #include "QCalculatorDec.h"
  5. class QCalculator
  6. {
  7. protected:
  8. QCalculatorUI* m_ui;
  9. QCalculatorDec m_cal;
  10. QCalculator();
  11. bool construct();
  12. public:
  13. static QCalculator* NewInstance();
  14. void show();
  15. ~QCalculator();
  16. };
  17. #endif // QCALCULATOR_H

QCalculator.cpp

  1. #include "QCalculator.h"
  2. QCalculator::QCalculator()
  3. {
  4. }
  5. bool QCalculator::construct()
  6. {
  7. m_ui = QCalculatorUI::NewInstance();
  8. if( m_ui != NULL )
  9. {
  10. m_ui->setCalculator(&m_cal);
  11. }
  12. return (m_ui != NULL);
  13. }
  14. QCalculator* QCalculator::NewInstance()
  15. {
  16. QCalculator* ret = new QCalculator();
  17. if( (ret == NULL) || !ret->construct() )
  18. {
  19. delete ret;
  20. ret = NULL;
  21. }
  22. return ret;
  23. }
  24. void QCalculator::show()
  25. {
  26. m_ui->show();
  27. }
  28. QCalculator::~QCalculator()
  29. {
  30. delete m_ui;
  31. }

QCalculatorDec.h

  1. #ifndef _CALCULATORCORE_H_
  2. #define _CALCULATORCORE_H_
  3. #include <QString>
  4. #include <QStack>
  5. #include <QQueue>
  6. #include "ICalculator.h"
  7. class QCalculatorDec : public ICalculator
  8. {
  9. protected:
  10. QString m_exp;
  11. QString m_result;
  12. bool isDigitOrDot(QChar c);
  13. bool isSymbol(QChar c);
  14. bool isSign(QChar c);
  15. bool isNumber(QString s);
  16. bool isOperator(QString s);
  17. bool isLeft(QString s);
  18. bool isRight(QString s);
  19. int priority(QString s);
  20. bool match(QQueue<QString>& exp);
  21. QString calculate(QQueue<QString>& exp);
  22. QString calculate(QString l, QString op, QString r);
  23. bool transform(QQueue<QString>& exp, QQueue<QString>& output);
  24. QQueue<QString> split(const QString& exp);
  25. public:
  26. QCalculatorDec();
  27. ~QCalculatorDec();
  28. bool expression(const QString& exp);
  29. QString expression();
  30. QString result();
  31. };
  32. #endif

 QCalculatorDec.cpp

  1. #include "QCalculatorDec.h"
  2. QCalculatorDec::QCalculatorDec()
  3. {
  4. m_exp = "";
  5. m_result = "";
  6. }
  7. QCalculatorDec::~QCalculatorDec()
  8. {
  9. }
  10. bool QCalculatorDec::isDigitOrDot(QChar c)
  11. {
  12. return (('0' <= c) && (c <= '9')) || (c == '.');
  13. }
  14. bool QCalculatorDec::isSymbol(QChar c)
  15. {
  16. return isOperator(c) || (c == '(') || (c == ')');
  17. }
  18. bool QCalculatorDec::isSign(QChar c)
  19. {
  20. return (c == '+') || (c == '-');
  21. }
  22. bool QCalculatorDec::isNumber(QString s)
  23. {
  24. bool ret = false;
  25. s.toDouble(&ret);
  26. return ret;
  27. }
  28. bool QCalculatorDec::isOperator(QString s)
  29. {
  30. return (s == "+") || (s == "-") || (s == "*") || (s == "/");
  31. }
  32. bool QCalculatorDec::isLeft(QString s)
  33. {
  34. return (s == "(");
  35. }
  36. bool QCalculatorDec::isRight(QString s)
  37. {
  38. return (s == ")");
  39. }
  40. int QCalculatorDec::priority(QString s)
  41. {
  42. int ret = 0;
  43. if( (s == "+") || (s == "-") )
  44. {
  45. ret = 1;
  46. }
  47. if( (s == "*") || (s == "/") )
  48. {
  49. ret = 2;
  50. }
  51. return ret;
  52. }
  53. bool QCalculatorDec::expression(const QString& exp)
  54. {
  55. bool ret = false;
  56. QQueue<QString> spExp = split(exp);
  57. QQueue<QString> postExp;
  58. m_exp = exp;
  59. if( transform(spExp, postExp) )
  60. {
  61. m_result = calculate(postExp);
  62. ret = (m_result != "Error");
  63. }
  64. else
  65. {
  66. m_result = "Error";
  67. }
  68. return ret;
  69. }
  70. QString QCalculatorDec::result()
  71. {
  72. return m_result;
  73. }
  74. QQueue<QString> QCalculatorDec::split(const QString& exp)
  75. {
  76. QQueue<QString> ret;
  77. QString num = "";
  78. QString pre = "";
  79. for(int i=0; i<exp.length(); i++)
  80. {
  81. if( isDigitOrDot(exp[i]) )
  82. {
  83. num += exp[i];
  84. pre = exp[i];
  85. }
  86. else if( isSymbol(exp[i]) )
  87. {
  88. if( !num.isEmpty() )
  89. {
  90. ret.enqueue(num);
  91. num.clear();
  92. }
  93. if( isSign(exp[i]) && ((pre == "") || (pre == "(") || isOperator(pre)) )
  94. {
  95. num += exp[i];
  96. }
  97. else
  98. {
  99. ret.enqueue(exp[i]);
  100. }
  101. pre = exp[i];
  102. }
  103. }
  104. if( !num.isEmpty() )
  105. {
  106. ret.enqueue(num);
  107. }
  108. return ret;
  109. }
  110. bool QCalculatorDec::match(QQueue<QString>& exp)
  111. {
  112. bool ret = true;
  113. int len = exp.length();
  114. QStack<QString> stack;
  115. for(int i=0; i<len; i++)
  116. {
  117. if( isLeft(exp[i]) )
  118. {
  119. stack.push(exp[i]);
  120. }
  121. else if( isRight(exp[i]) )
  122. {
  123. if( !stack.isEmpty() && isLeft(stack.top()) )
  124. {
  125. stack.pop();
  126. }
  127. else
  128. {
  129. ret = false;
  130. break;
  131. }
  132. }
  133. }
  134. return ret && stack.isEmpty();
  135. }
  136. bool QCalculatorDec::transform(QQueue<QString>& exp, QQueue<QString>& output)
  137. {
  138. bool ret = match(exp);
  139. QStack<QString> stack;
  140. output.clear();
  141. while( ret && !exp.isEmpty() )
  142. {
  143. QString e = exp.dequeue();
  144. if( isNumber(e) )
  145. {
  146. output.enqueue(e);
  147. }
  148. else if( isOperator(e) )
  149. {
  150. while( !stack.isEmpty() && (priority(e) <= priority(stack.top())) )
  151. {
  152. output.enqueue(stack.pop());
  153. }
  154. stack.push(e);
  155. }
  156. else if( isLeft(e) )
  157. {
  158. stack.push(e);
  159. }
  160. else if( isRight(e) )
  161. {
  162. while( !stack.isEmpty() && !isLeft(stack.top()) )
  163. {
  164. output.enqueue(stack.pop());
  165. }
  166. if( !stack.isEmpty() )
  167. {
  168. stack.pop();
  169. }
  170. }
  171. else
  172. {
  173. ret = false;
  174. }
  175. }
  176. while( !stack.isEmpty() )
  177. {
  178. output.enqueue(stack.pop());
  179. }
  180. if( !ret )
  181. {
  182. output.clear();
  183. }
  184. return ret;
  185. }
  186. QString QCalculatorDec::calculate(QString l, QString op, QString r)
  187. {
  188. QString ret = "Error";
  189. if( isNumber(l) && isNumber(r) )
  190. {
  191. double lp = l.toDouble();
  192. double rp = r.toDouble();
  193. if( op == "+" )
  194. {
  195. ret.sprintf("%f", lp + rp);
  196. }
  197. else if( op == "-" )
  198. {
  199. ret.sprintf("%f", lp - rp);
  200. }
  201. else if( op == "*" )
  202. {
  203. ret.sprintf("%f", lp * rp);
  204. }
  205. else if( op == "/" )
  206. {
  207. const double P = 0.000000000000001;
  208. if( (-P < rp) && (rp < P) )
  209. {
  210. ret = "Error";
  211. }
  212. else
  213. {
  214. ret.sprintf("%f", lp / rp);
  215. }
  216. }
  217. else
  218. {
  219. ret = "Error";
  220. }
  221. }
  222. return ret;
  223. }
  224. QString QCalculatorDec::calculate(QQueue<QString>& exp)
  225. {
  226. QString ret = "Error";
  227. QStack<QString> stack;
  228. while( !exp.isEmpty() )
  229. {
  230. QString e = exp.dequeue();
  231. if( isNumber(e) )
  232. {
  233. stack.push(e);
  234. }
  235. else if( isOperator(e) )
  236. {
  237. QString rp = !stack.isEmpty() ? stack.pop() : "";
  238. QString lp = !stack.isEmpty() ? stack.pop() : "";
  239. QString result = calculate(lp, e, rp);
  240. if( result != "Error" )
  241. {
  242. stack.push(result);
  243. }
  244. else
  245. {
  246. break;
  247. }
  248. }
  249. else
  250. {
  251. break;
  252. }
  253. }
  254. if( exp.isEmpty() && (stack.size() == 1) && isNumber(stack.top()) )
  255. {
  256. ret = stack.pop();
  257. }
  258. return ret;
  259. }

QCalculatorUI.h

  1. #ifndef _QCALCULATORUI_H_
  2. #define _QCALCULATORUI_H_
  3. #include <QWidget>
  4. #include <QLineEdit>
  5. #include <QPushButton>
  6. #include "ICalculator.h"
  7. class QCalculatorUI : public QWidget
  8. {
  9. Q_OBJECT
  10. private:
  11. QLineEdit* m_edit;
  12. QPushButton* m_buttons[20];
  13. ICalculator* m_cal;
  14. QCalculatorUI();
  15. bool construct();
  16. private slots:
  17. void onButtonClicked();
  18. public:
  19. static QCalculatorUI* NewInstance();
  20. void show();
  21. void setCalculator(ICalculator* cal);
  22. ICalculator* getCalculator();
  23. ~QCalculatorUI();
  24. };
  25. #endif

QCalculatorUI.cpp

  1. #include "QCalculatorUI.h"
  2. #include <QDebug>
  3. QCalculatorUI::QCalculatorUI() : QWidget(NULL, Qt::WindowCloseButtonHint)
  4. {
  5. m_cal = NULL;
  6. }
  7. bool QCalculatorUI::construct()
  8. {
  9. bool ret = true;
  10. const char* btnText[20] =
  11. {
  12. "7", "8", "9", "+", "(",
  13. "4", "5", "6", "-", ")",
  14. "1", "2", "3", "*", "<-",
  15. "0", ".", "=", "/", "C",
  16. };
  17. m_edit = new QLineEdit(this);
  18. if( m_edit != NULL )
  19. {
  20. m_edit->move(10, 10);
  21. m_edit->resize(240, 30);
  22. m_edit->setReadOnly(true);
  23. m_edit->setAlignment(Qt::AlignRight);
  24. }
  25. else
  26. {
  27. ret = false;
  28. }
  29. for(int i=0; (i<4) && ret; i++)
  30. {
  31. for(int j=0; (j<5) && ret; j++)
  32. {
  33. m_buttons[i*5 + j] = new QPushButton(this);
  34. if( m_buttons[i*5 + j] != NULL )
  35. {
  36. m_buttons[i*5 + j]->resize(40, 40);
  37. m_buttons[i*5 + j]->move(10 + (10 + 40)*j, 50 + (10 + 40)*i);
  38. m_buttons[i*5 + j]->setText(btnText[i*5 + j]);
  39. connect(m_buttons[i*5 + j], SIGNAL(clicked()), this, SLOT(onButtonClicked()));
  40. }
  41. else
  42. {
  43. ret = false;
  44. }
  45. }
  46. }
  47. return ret;
  48. }
  49. QCalculatorUI* QCalculatorUI::NewInstance()
  50. {
  51. QCalculatorUI* ret = new QCalculatorUI();
  52. if( (ret == NULL) || !ret->construct() )
  53. {
  54. delete ret;
  55. ret = NULL;
  56. }
  57. return ret;
  58. }
  59. void QCalculatorUI::show()
  60. {
  61. QWidget::show();
  62. setFixedSize(width(), height());
  63. }
  64. void QCalculatorUI::onButtonClicked()
  65. {
  66. QPushButton* btn = dynamic_cast<QPushButton*>(sender());
  67. if( btn != NULL )
  68. {
  69. QString clickText = btn->text();
  70. if( clickText == "<-" )
  71. {
  72. QString text = m_edit->text();
  73. if( text.length() > 0 )
  74. {
  75. text.remove(text.length()-1, 1);
  76. m_edit->setText(text);
  77. }
  78. }
  79. else if( clickText == "C" )
  80. {
  81. m_edit->setText("");
  82. }
  83. else if( clickText == "=" )
  84. {
  85. if( m_cal != NULL )
  86. {
  87. m_cal->expression(m_edit->text());
  88. m_edit->setText(m_cal->result());
  89. }
  90. }
  91. else
  92. {
  93. m_edit->setText(m_edit->text() + clickText);
  94. }
  95. }
  96. }
  97. void QCalculatorUI::setCalculator(ICalculator* cal)
  98. {
  99. m_cal = cal;
  100. }
  101. ICalculator* QCalculatorUI::getCalculator()
  102. {
  103. return m_cal;
  104. }
  105. QCalculatorUI::~QCalculatorUI()
  106. {
  107. }

main.cpp

  1. #include <QApplication>
  2. #include "QCalculator.h"
  3. int main(int argc, char *argv[])
  4. {
  5. QApplication a(argc, argv);
  6. QCalculator* cal = QCalculator::NewInstance();
  7. int ret = -1;
  8. if( cal != NULL )
  9. {
  10. cal->show();
  11. ret = a.exec();
  12. delete cal;
  13. }
  14. return ret;
  15. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/291274?site
推荐阅读
相关标签
  

闽ICP备14008679号