• 【Qt】从开源项目QCAD中学习如何增强QLineEdit控件


    1 背景

    Qt5 中有个很基本的单行输入框控件,就是 QLineEdit,类似于HTML中的input标签。

    QCAD开源项目中,其主界面中有个供用户输入绘图命令的单行输入框控件,其可以实现类似 Linux 终端的简单效果:

    1. 上键显示最近的一条命令
    2. 上下键在历史命令里面查找命令
    3.  Ctrl+V键粘贴命令
    4.  Ctrl+L键清空命令

    功能简单,但是也算是看到了 Qt 的较中级的用法,就是继承和扩展Qt 原生组件。

    2 代码说明

    首先继承 QLineEdit 类。

    新增了两个字段/属性,用于存储命令的字符串列表 history,还有一个迭代器 it,指代命令在列表中的位置。

    重载 keyPressEvent 函数,用于支持自定义的Up,Down,Ctrl+V,Ctrl+L按键事件。

    注意:源代码非完整代码,无法运行。

    3 源代码

    3.1 头文件 RCommandLine.h

    1. /**
    2. * Copyright (c) 2011-2018 by Andrew Mustun. All rights reserved.
    3. *
    4. * This file is part of the QCAD project.
    5. *
    6. * QCAD is free software: you can redistribute it and/or modify
    7. * it under the terms of the GNU General Public License as published by
    8. * the Free Software Foundation, either version 3 of the License, or
    9. * (at your option) any later version.
    10. *
    11. * QCAD is distributed in the hope that it will be useful,
    12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
    13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    14. * GNU General Public License for more details.
    15. *
    16. * You should have received a copy of the GNU General Public License
    17. * along with QCAD.
    18. */
    19. #ifndef RCOMMANDLINE_H_
    20. #define RCOMMANDLINE_H_
    21. #include "gui_global.h"
    22. #include
    23. #include
    24. #include
    25. #include
    26. /**
    27. * \scriptable
    28. * \ingroup gui
    29. */
    30. class QCADGUI_EXPORT RCommandLine: public QLineEdit {
    31. Q_OBJECT
    32. signals:
    33. void clearHistory();
    34. void commandConfirmed(const QString& command);
    35. void completeCommand(const QString& command);
    36. void escape();
    37. public:
    38. RCommandLine(QWidget* parent = 0);
    39. QString getLastCommand();
    40. void appendCommand(const QString& cmd);
    41. QStringList getHistory() const;
    42. void setHistory(QStringList& h);
    43. void triggerCommand(const QString& cmd) {
    44. emit commandConfirmed(cmd);
    45. }
    46. public slots:
    47. void paste();
    48. protected:
    49. virtual void keyPressEvent(QKeyEvent* event);
    50. virtual bool event(QEvent* event);
    51. private:
    52. QStringList history;
    53. QStringList::iterator it;
    54. };
    55. Q_DECLARE_METATYPE(RCommandLine*)
    56. #endif

    3.2  RCommandLine.cpp

    1. /**
    2. * Copyright (c) 2011-2018 by Andrew Mustun. All rights reserved.
    3. *
    4. * This file is part of the QCAD project.
    5. *
    6. * QCAD is free software: you can redistribute it and/or modify
    7. * it under the terms of the GNU General Public License as published by
    8. * the Free Software Foundation, either version 3 of the License, or
    9. * (at your option) any later version.
    10. *
    11. * QCAD is distributed in the hope that it will be useful,
    12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
    13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    14. * GNU General Public License for more details.
    15. *
    16. * You should have received a copy of the GNU General Public License
    17. * along with QCAD.
    18. */
    19. #include
    20. #include
    21. #include
    22. #include
    23. #if QT_VERSION >= 0x050000
    24. #include
    25. #else
    26. #include
    27. #endif
    28. #include "RCommandLine.h"
    29. #include "RDebug.h"
    30. RCommandLine::RCommandLine(QWidget* parent) :
    31. QLineEdit(parent), it(history.end()) {
    32. }
    33. QString RCommandLine::getLastCommand() {
    34. if (history.isEmpty()) {
    35. return QString();
    36. }
    37. return history.last();
    38. }
    39. void RCommandLine::appendCommand(const QString& cmd) {
    40. if (!cmd.isEmpty() && (history.isEmpty() || history.last() != cmd)) {
    41. history.append(cmd);
    42. }
    43. it = history.end();
    44. }
    45. QStringList RCommandLine::getHistory() const {
    46. return history;
    47. }
    48. void RCommandLine::setHistory(QStringList& h) {
    49. history = h;
    50. it = history.end();
    51. }
    52. void RCommandLine::paste() {
    53. #if QT_VERSION >= 0x050000
    54. QClipboard* cb = QGuiApplication::clipboard();
    55. #else
    56. QClipboard* cb = QApplication::clipboard();
    57. #endif
    58. //qDebug("pasting: " + cb.text());
    59. QString text = cb->text();
    60. // multi line paste and enter:
    61. if (text.contains("\n")) {
    62. QStringList lines = text.split('\n');
    63. for (int i=0; ilength(); i++) {
    64. //qDebug("line: " + lines[i]);
    65. emit commandConfirmed(lines[i]);
    66. }
    67. }
    68. else {
    69. // single line paste only:
    70. QLineEdit::paste();
    71. }
    72. }
    73. bool RCommandLine::event(QEvent* event) {
    74. if (event->type() == QEvent::KeyPress) {
    75. QKeyEvent* ke = dynamic_cast (event);
    76. if (ke->key() == Qt::Key_Tab) {
    77. emit completeCommand(text());
    78. return true;
    79. }
    80. }
    81. return QLineEdit::event(event);
    82. }
    83. void RCommandLine::keyPressEvent(QKeyEvent* event) {
    84. switch (event->key()) {
    85. case Qt::Key_L:
    86. if (event->modifiers() == Qt::ControlModifier) {
    87. emit clearHistory();
    88. return;
    89. }
    90. break;
    91. case Qt::Key_V:
    92. if (event->modifiers() == Qt::ControlModifier) {
    93. paste();
    94. return;
    95. }
    96. break;
    97. case Qt::Key_Enter:
    98. case Qt::Key_Return: {
    99. QString t = text();
    100. // if (!t.isEmpty() && (history.isEmpty() || history.last() != t)) {
    101. // history.append(t);
    102. // }
    103. it = history.end();
    104. emit commandConfirmed(t);
    105. }
    106. break;
    107. case Qt::Key_Up:
    108. if (it != history.begin()) {
    109. it--;
    110. setText(*it);
    111. }
    112. return;
    113. break;
    114. case Qt::Key_Down:
    115. if (it != history.end()) {
    116. it++;
    117. if (it != history.end()) {
    118. setText(*it);
    119. } else {
    120. clear();
    121. }
    122. }
    123. return;
    124. break;
    125. default:
    126. break;
    127. }
    128. QLineEdit::keyPressEvent(event);
    129. }

    以上源代码仅供学习交流,版权归QCAD项目所有。

  • 相关阅读:
    Springboot websocket前端无法访问到,Websocket因AOP代理 前端无法请求到
    redis的淘汰机制分析
    香橙派5plus从ssd启动Ubuntu
    淘宝API接口获取商品信息,订单管理,库存管理,数据分析
    ue4使用Niagara粒子实现下雨效果,使用蓝图调节雨量
    Java 多线程 —— 内存合并
    CRUD搬砖两三年了,怎么阅读Spring源码?
    (附源码)springboot助农电商系统 毕业设计 081919
    【深度学习】NLP,Transformer讲解,代码实战
    unity学习之汇总解答
  • 原文地址:https://blog.csdn.net/qilei2010/article/details/128211368