window 10 平板不好搞
#pragma once
#ifndef FXKEYBOARD_H
#define FXKEYBOARD_H
#include <QPushButton>
#include <QGridLayout>
#include <QLineEdit>
#include <QDialog>
#include <QEvent>
#include <QDebug>
#include <QMouseEvent>
#include <QCheckBox>
#ifndef KB_Qwert_Upper
#define KB_Qwert_Upper 0 //全键盘 大写 (A-Z 0-9 + - * / . = Space) 可以通过capslock 切换大小写
#endif
#ifndef KB_Qwert_Lower
#define KB_Qwert_Lower 1 //全键盘 小写 (a-z 0-9 + - * / . = Space)可以通过capslock 切换大小写
#endif
#ifndef KB_Letter_Upper
#define KB_Letter_Upper 2 //字母键盘 大写(A-Z Space)可以通过capslock 切换大小写
#endif
#ifndef KB_Letter_Lower
#define KB_Letter_Lower 3 //字母键盘 小写(a-z Space)可以通过capslock 切换大小写
#endif
#ifndef KB_Number
#define KB_Number 4 //数字键盘 (0-9 + - * / = .)
#endif
#ifndef KB_Hex
#define KB_Hex 5 //十六进制键盘 (0-9 A-F)
#endif
#define SPACE "Space"
#define CAPSLOCK "CapsLock"
#define BACKSPACE "Backspace"
#define SPACE "Space"
#define DEL "Del"
#define LEFT "<-"
#define RIGHT "->"
#define HIDE "Hide"
#define NUMBER "&&123"
#define LETTER "abc"
#define KEY_SPACE 5
#define _KEY_WIDTH 95
#define _KEY_HEIGHT 95
class FXPushButton : public QPushButton
{
Q_OBJECT
public:
FXPushButton(QWidget *parent) : QPushButton(parent)
{
connect(this, &FXPushButton::clicked, this, [=](bool isClicked)
{
emit signalClicked(this->objectName());
});
}
virtual~FXPushButton()
{
}
signals:
void signalClicked(QString id);
};
class KeyBoard : public QDialog
{
Q_OBJECT
public:
KeyBoard(QWidget *parent, int32_t type);
virtual ~KeyBoard();
void BindingEdit(QLineEdit * edit);
protected:
virtual bool eventFilter(QObject *obj, QEvent *ev) override;
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override;
virtual void showEvent(QShowEvent *event) override;
virtual void resizeEvent(QResizeEvent *event) override;
signals:
void keyPressed(const QString id);
public slots:
void OnButtonClicked(const QString &id);
private:
void InitKeyBoard(int32_t type);
FXPushButton* CreateKey(QString id, QSize size = QSize(_KEY_WIDTH, _KEY_WIDTH));
FXPushButton* CreateKey2(QString id, QSize size = QSize(_KEY_WIDTH * 2 + KEY_SPACE, _KEY_WIDTH));
FXPushButton* CreateKeyCAPSLOCK(QString id, QSize size = QSize(_KEY_WIDTH * 2 + KEY_SPACE, _KEY_WIDTH));
void CreateHex();
void CreateNumber();
void InitRootLayout();
void CreateLetterKeyBoard(int32_t type);
void CreateQwetyKeyBoard(int32_t type);
void LetterCaseConversion(bool update);
void ClearButtons(QGridLayout * layout);
QPoint calcStartPoint();
private:
QLineEdit *mInputEdit = nullptr;
QGridLayout *mKeyLayout = nullptr;
QVBoxLayout *mRootLayout = nullptr;
QWidget *mRootWidget = nullptr;
int32_t mCurrentType;//键盘类型 KB_Letter_Upper; KB_Qwert_Upper; KB_Number; KB_Hex;
bool mIsMoveNoClicked = false;//移动状态不响应按钮点击
bool mIsMovable = false;
QPoint mLastMousePos;
QRect mScreenRect;
int KEY_WIDTH = 100;
int KEY_HEIGHT = 100;
};
#endif
#include "FXFramework/Widgets/KeyBoard.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QDebug>
KeyBoard::KeyBoard(QWidget *parent, int32_t type)
: QDialog(parent, Qt::Window | Qt::WindowTitleHint | Qt::FramelessWindowHint | Qt::Tool | Qt::WindowDoesNotAcceptFocus | Qt::WindowStaysOnTopHint)
{
QDesktopWidget* desktopWidget = QApplication::desktop();
mScreenRect = desktopWidget->screenGeometry();
if (mScreenRect.width() > 1560)
{
KEY_WIDTH = 130;
}
this->setAttribute(Qt::WA_DeleteOnClose);
this->setWindowOpacity(0.9); //达到比较好的淡出效果,需要将窗口设置完全透明,否则会有卡顿的效果
this->setStyleSheet("background-color: #24272A;");
//this->setAttribute(Qt::WA_TranslucentBackground, true);
this->setContentsMargins(0, 0, 0, 0);
this->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
mCurrentType = type;
InitKeyBoard(mCurrentType);
mLastMousePos = this->pos();
}
KeyBoard::~KeyBoard()
{
ClearButtons(mKeyLayout);
if (mKeyLayout != nullptr)
{
delete mKeyLayout;
mKeyLayout = nullptr;
}
if (mRootWidget != nullptr)
{
delete mRootWidget;
mRootWidget = nullptr;
}
if (mRootLayout != nullptr)
{
delete mRootLayout;
mRootLayout = nullptr;
}
}
void KeyBoard::BindingEdit(QLineEdit * edit)
{
mInputEdit = edit;
}
void KeyBoard::resizeEvent(QResizeEvent *event)
{
//this->resize(this->size());
qDebug() << event->type() << this->size();
//QWidget::resizeEvent(event);
}
void KeyBoard::showEvent(QShowEvent *event)
{
this->move(calcStartPoint());
}
QPoint KeyBoard::calcStartPoint()
{
Q_ASSERT(mInputEdit != nullptr);
QPoint pt = mInputEdit->mapToGlobal(QPoint(0, 0));
int h = mInputEdit->height();
int x = pt.x();
int y = pt.y();
//保证键盘在屏幕上,并且不遮挡输入框
int div = mScreenRect.width() - this->width(); //计算屏幕和键盘差值
if (div < 0)
{
x = 0;
}
else
{
x = div / 2; //计算居中
}
int sum = y + h + this->height();
if (sum > mScreenRect.height()) //键盘超出屏幕
{
//键盘放到输入框上面
y = y - this->height();
if (y < 0)
{
//键盘遮挡输入框,键盘透明
y = 0;
}
}
else
{
//键盘放到输入框下面
y = y + h;
}
return QPoint(x, y);
}
void KeyBoard::mousePressEvent(QMouseEvent * event)
{
QPoint point = event->pos();
QRect rect = this->rect();
if (rect.contains(point))
{
mIsMovable = true;
mLastMousePos = event->globalPos();
}
else
{
mIsMovable = false;
}
}
void KeyBoard::mouseMoveEvent(QMouseEvent * event)
{
if (mIsMovable)
{
QPoint p = event->globalPos() - mLastMousePos + this->pos();
if (p.x() < 0)//左
{
p.setX(0);
}
if (p.y() < 0)//上
{
p.setY(0);
}
if (p.x() + this->width() > mScreenRect.width())//右
{
p.setX(mScreenRect.width() - this->width());
}
if (p.y() + this->height() > mScreenRect.height())//下
{
p.setY(mScreenRect.height() - this->height());
}
move(p);
mLastMousePos = event->globalPos();
mIsMoveNoClicked = true;
}
}
void KeyBoard::mouseReleaseEvent(QMouseEvent * event)
{
mIsMovable = false;
}
bool KeyBoard::eventFilter(QObject *obj, QEvent *event)
{
QMouseEvent *mouseEvent;
switch (event->type())
{
case QEvent::MouseButtonPress:
mouseEvent = static_cast<QMouseEvent*>(event);
mousePressEvent(mouseEvent);
break;
case QEvent::MouseMove:
mouseEvent = static_cast<QMouseEvent*>(event);
mouseMoveEvent(mouseEvent);
break;
case QEvent::MouseButtonRelease:
mouseEvent = static_cast<QMouseEvent*>(event);
mouseReleaseEvent(mouseEvent);
break;
}
// pass the event on to the parent class
return QWidget::eventFilter(obj, event);
}
void KeyBoard::InitKeyBoard(int32_t type)
{
switch (type)
{
case KB_Qwert_Upper:
case KB_Qwert_Lower:
CreateQwetyKeyBoard(type);
break;
case KB_Letter_Upper:
case KB_Letter_Lower:
CreateLetterKeyBoard(type);
break;
case KB_Number:
CreateNumber();
break;
case KB_Hex:
CreateHex();
break;
default:
break;
}
}
void KeyBoard::InitRootLayout()
{
if (mKeyLayout == nullptr)
{
mKeyLayout = new QGridLayout(this);
mKeyLayout->setSpacing(KEY_SPACE);
mRootWidget = new QWidget(this);
mRootWidget->setLayout(mKeyLayout);
mRootLayout = new QVBoxLayout(this);
mRootLayout->addWidget(mRootWidget);
mRootLayout->setAlignment(Qt::AlignCenter);
}
else
{
ClearButtons(mKeyLayout);
}
}
FXPushButton * KeyBoard::CreateKey(QString id, QSize size)
{
FXPushButton *btn = new FXPushButton(this);
btn->setText(id);
btn->setMinimumSize(size);
btn->setObjectName(id);
btn->setFont(QFont("\"Microsoft YeHei\"", 24, QFont::Normal));
btn->setStyleSheet("QPushButton{background-color:#4A4B4E;color:white;border:none;}"
/*"QPushButton:pressed{background-color:#030FD0;color:white;border:none;}"*/);
btn->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, QSizePolicy::PushButton));
btn->installEventFilter(this);
connect(btn, &FXPushButton::signalClicked, this, &KeyBoard::OnButtonClicked);
return btn;
}
FXPushButton * KeyBoard::CreateKey2(QString id, QSize size)
{
FXPushButton *btn = new FXPushButton(this);
btn->setText(id);
btn->setMinimumSize(size);
btn->setObjectName(id);
btn->setFont(QFont("\"Microsoft YeHei\"", 24, QFont::Normal));
btn->setStyleSheet("QPushButton{background-color:#4A4B4E;color:white;border:none;}"
/*"QPushButton:pressed{background-color:#030FD0;color:white;border:none;}"*/);
btn->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, QSizePolicy::PushButton));
btn->installEventFilter(this);
connect(btn, &FXPushButton::signalClicked, this, &KeyBoard::OnButtonClicked);
return btn;
}
FXPushButton * KeyBoard::CreateKeyCAPSLOCK(QString id, QSize size)
{
FXPushButton *btn = new FXPushButton(this);
btn->setText(id);
btn->setCheckable(true);
btn->setMinimumSize(size);
btn->setObjectName(id);
btn->setFont(QFont("\"Microsoft YeHei\"", 24, QFont::Normal));
btn->setStyleSheet("QPushButton:checked{background:#030FD0;color:white;border:none;}"
"QPushButton{background:#4A4B4E;color:white;border:none;}");
btn->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, QSizePolicy::PushButton));
btn->installEventFilter(this);
btn->setChecked(true);
connect(btn, &FXPushButton::clicked, this, [=]() {LetterCaseConversion(true); });
return btn;
}
void KeyBoard::CreateHex()
{
InitRootLayout();
mKeyLayout->addWidget(CreateKey("0"), 0, 0, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("1"), 0, 1, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("2"), 0, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("3"), 0, 3, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("4"), 0, 4, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("5"), 0, 5, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey2(BACKSPACE), 0, 6, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("6"), 1, 0, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("7"), 1, 1, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("8"), 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("9"), 1, 3, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("A"), 1, 4, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("B"), 1, 5, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey(LEFT), 1, 6, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey(RIGHT), 1, 7, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("C"), 2, 0, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("D"), 2, 1, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("E"), 2, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("F"), 2, 3, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey2(DEL), 2, 4, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey2(HIDE), 2, 6, 1, 2, Qt::AlignCenter);
//mRootWidget->resize(QSize(KEY_WIDTH * 8 + KEY_SPACE * 7, KEY_HEIGHT * 3 + KEY_SPACE * 2));
}
void KeyBoard::CreateNumber()
{
InitRootLayout();
mKeyLayout->addWidget(CreateKey("0"), 0, 0, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("1"), 0, 1, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("2"), 0, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("3"), 0, 3, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("4"), 0, 4, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("5"), 0, 5, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey2(DEL), 0, 6, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("6"), 1, 0, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("7"), 1, 1, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("8"), 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("9"), 1, 3, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("."), 1, 4, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("="), 1, 5, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey(LEFT), 1, 6, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey(RIGHT), 1, 7, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey(LETTER), 2, 0, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("+"), 2, 1, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("-"), 2, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("*"), 2, 3, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("/"), 2, 4, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey2(SPACE), 2, 5, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey(HIDE), 2, 7, Qt::AlignCenter);
//mRootWidget->resize(QSize(KEY_WIDTH * 8 + KEY_SPACE * 7, KEY_HEIGHT * 3 + KEY_SPACE * 2));
}
void KeyBoard::CreateLetterKeyBoard(int32_t type)
{
InitRootLayout();
FXPushButton *ButtonHide = CreateKey(HIDE);
mKeyLayout->addWidget(CreateKey("Q"), 0, 0, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("W"), 0, 2, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("E"), 0, 4, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("R"), 0, 6, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("T"), 0, 8, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("Y"), 0, 10, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("U"), 0, 12, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("I"), 0, 14, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("O"), 0, 16, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("P"), 0, 18, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKeyCAPSLOCK(CAPSLOCK), 0, 20, 1, 4, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("A"), 1, 1, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("S"), 1, 3, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("D"), 1, 5, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("F"), 1, 7, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("G"), 1, 9, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("H"), 1, 11, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("J"), 1, 13, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("K"), 1, 15, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("L"), 1, 17, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey2(SPACE), 1, 19, 1, 4, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey(NUMBER), 2, 0, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(ButtonHide, 2, 0, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("Z"), 2, 2, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("X"), 2, 4, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("C"), 2, 6, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("V"), 2, 8, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("B"), 2, 10, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("N"), 2, 12, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey("M"), 2, 14, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey(LEFT), 2, 16, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey(RIGHT), 2, 18, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(CreateKey(DEL), 2, 20, 1, 2, Qt::AlignCenter);
mKeyLayout->addWidget(ButtonHide, 2, 22, 1, 2, Qt::AlignCenter);
//mRootWidget->resize(QSize(KEY_WIDTH * 13 + KEY_SPACE * 12, KEY_HEIGHT * 3 + KEY_SPACE * 2));
if (KB_Letter_Lower == type)
{
LetterCaseConversion(false);
}
}
void KeyBoard::CreateQwetyKeyBoard(int32_t type)
{
CreateLetterKeyBoard(type);
}
void KeyBoard::OnButtonClicked(const QString &id)
{
qDebug() << "OnButtonClicked id : " << id;
if (mIsMoveNoClicked)
{
mIsMoveNoClicked = false;
return;
}
if (id.compare(CAPSLOCK) == 0)
{
LetterCaseConversion(true);
return;
}
if (id.compare(HIDE) == 0)
{
this->hide();
if (mInputEdit != nullptr)
{
mInputEdit->clearFocus();
}
return;
}
if (id.compare(NUMBER) == 0)
{
CreateNumber();
//this->resize(mRootWidget->size());
//this->adjustSize();//由大到小会闪烁
return;
}
if (id.compare(LETTER) == 0)
{
CreateLetterKeyBoard(KB_Letter_Upper);
return;
}
if (mInputEdit != nullptr)
{
QString text = mInputEdit->text();
if (id.compare(DEL) == 0)
{
int32_t pos = mInputEdit->cursorPosition();
mInputEdit->setCursorPosition(pos - 1);
mInputEdit->del();
}
else if (id.compare(BACKSPACE) == 0)
{
mInputEdit->backspace();
}
else if (id.compare(LEFT) == 0)
{
mInputEdit->cursorBackward(false, 1);
}
else if (id.compare(RIGHT) == 0)
{
mInputEdit->cursorForward(false, 1);
}
else if (id.compare(SPACE) == 0)
{
mInputEdit->insert(" ");
}
else
{
mInputEdit->insert(id);
}
}
emit keyPressed(id);
}
void KeyBoard::LetterCaseConversion(bool update)
{
if (mKeyLayout == nullptr)
{
return;
}
int size = mKeyLayout->count();
for (size_t i = 0; i < size; i++)
{
QLayoutItem *item = mKeyLayout->itemAt(i);
QWidget * widget = item->widget();
FXPushButton *btn = (FXPushButton *)widget;
QString key = btn->objectName();
if (key.length() == 1)
{
QByteArray ba = key.toLatin1(); // must
char* ch = ba.data();
QString newKey = key;
if ((*ch) >= 'a' && (*ch) <= 'z')
{
newKey = key.toUpper();
}
else if ((*ch) >= 'A' && (*ch) <= 'Z')
{
newKey = key.toLower();
}
btn->setObjectName(newKey);
btn->setText(newKey);
}
}
if (update)
{
this->update();
}
}
void KeyBoard::ClearButtons(QGridLayout * layout)
{
int32_t count = layout->count();
while (count > 0)
{
QLayoutItem * item = layout->itemAt(0);
QWidget* widget = item->widget();
if (widget != nullptr)
{
FXPushButton *btn = (FXPushButton *)widget;
btn->removeEventFilter(this);
layout->removeItem(item);
delete btn;
btn = nullptr;
}
count = layout->count();
}
}