轻量级Qt键盘-原理篇

以类图,顺序图为切入点分析键盘使用原理。

1.类图分析

1.1 AbstractKeyboard与Keyboard
  类图中AbstractKeyboard继承于QWidget,而Keyboard则继承于AbstractKeyboard。

  或许有人会问,为什么Keyboard直接继承于QWidget这样更简单直接?
这里看情况,在单个键盘的情况下这种做法是简单直接。如何是存在多个键盘(数字键盘,字母键盘等),我们需要切换起来就会变得很麻烦

  AbstractKeyboard提供namesetName接口是为了标识多个键盘的情况。
类图
1.2 KeyboardKeyButton

  • Keyboard存在多个KeyButton;
  • Keyboard类通过构造多个按键并使用(h1(),h2(),h3(),h4())进行布局。
  • 当用户按下切换大小写按钮触发事先构造绑定在Keyboard类的switchCapsLock槽函数。

1.3 KeyButtonKeyMode

  • 由于KeyButtonKeyMode为了表达按键的多种显示,比如小写q,当按下大写切换就会变为大写Q,当按下字符切换就会切换到数字1
  • KeyMode的Mode包含按键的key值,按键的value,按键在界面的显示值,还有按键的类型​。

    2.用户使用键盘顺序图

    顺序图

3. 用户切换大小写键盘为例

顺序图

附录

  • 对应plantUML类图源码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    @startuml
    skinparam classAttributeIconSize -1
    QWidget <|-- AbstractKeyboard
    AbstractKeyboard <|-- Keyboard
    Keyboard o-right- "1..*" KeyButton
    KeyButton o-up- "1" KeyMode
    QPushButton <|-down- KeyButton
    package KeyMode {
    Mode o-- Type
    }

    class QWidget {
    ..internal..
    }

    class QPushButton {
    ..internal..
    }

    class AbstractKeyboard {
    + name(): QString
    + setName(QString)
    + onKeyPressed(int, QString)
    + [signal] keyPressed(int, QString)
    }

    class Keyboard {
    - switchCapsLock()
    - switchSpecialChar()
    - switchEnOrCh()
    - h1():QHBoxLayout
    - h2():QHBoxLayout
    - h3():QHBoxLayout
    - h4():QHBoxLayout
    }

    class KeyButton {
    + KeyButton(const QList<Mode>, QWidget *)
    + mode():Mode
    + switchCapsLock()
    + switchSpecialChar()
    + switching()
    + [signals] pressed(int,QString)
    }

    enum Type {
    Auto
    LowerCase
    UpperCase
    SpecialChar
    }

    class Mode<<(S,#ff7700)>> {
    + key:int
    + value:QString
    + display:QString
    + type:Type
    }

    hide QWidget fields
    hide AbstractKeyboard fields
    hide Keyboard fields
    hide KeyButton fields
    hide Type method
    hide Mode method
    @enduml
  • 对应plantUML顺序图源码

    1
    2
    3
    4
    5
    6
    7
    @startuml
    actor 使用者
    使用者 -> KeyButton: 按下键盘按钮
    KeyButton -> Keyboard: 发送pressed信号
    Keyboard -> AbstractKeyboard: 触发onKeyPressed槽函数
    AbstractKeyboard -> QApplication:向QApplication发送按键事件
    @enduml
1
2
3
4
5
6
7
8
@startuml
actor 使用者
使用者 -> KeyButton: 按下切换大小写按钮
KeyButton -> Keyboard: 发送pressed信号
Keyboard -> Keyboard: 触发switchCapsLock槽函数
Keyboard -> KeyButton: 遍历调用switchCapsLock函数
KeyButton -> KeyButton: 根据Mode的模式显示对应字符
@enduml