之前写过的V2018版本的输入法,本来已经很完善了,不打算更新升级了,最近有个朋友找我定制一个输入法,需要高仿一个苹果MAC电脑的输入法,MAC操作系统的审美无疑是相当棒的,于是乎直接拿以前的输入法高仿了一个,由于之前有做过输入法这块的开发,而且改进了四年,各种需求都遇到过,陆陆续续完善了很多年,所以这个高仿起来难度不大,而且要支持滑动选词,直接撸代码。
体验地址:https://pan.baidu.com/s/1vIyEdB4QGo5OvxLYj7kq5g 提取码:sysn
bool frmInput2019::eventFilter(QObject *watched, QEvent *event)
{
if (watched == this) {
//处理自身拖动
static QPoint mousePoint;
static bool mousePressed = false;
QMouseEvent *mouseEvent = static_cast(event);
//按下的时候记住坐标,移动到鼠标松开的位置
if (event->type() == QEvent::MouseButtonPress) {
if (mouseEvent->button() == Qt::LeftButton) {
mousePressed = true;
mousePoint = mouseEvent->globalPos() - this->pos();
return true;
}
} else if (event->type() == QEvent::MouseButtonRelease) {
mousePressed = false;
return true;
} else if (event->type() == QEvent::MouseMove) {
if (mousePressed && (mouseEvent->buttons() && Qt::LeftButton && position != "bottom")) {
this->move(mouseEvent->globalPos() - mousePoint);
this->update();
return true;
}
}
} else if (watched == ui->labMore) {
if (event->type() == QEvent::MouseButtonPress) {
if (inputType == "chinese" && !upper && labCn.first()->isEnabled()) {
if (!ui->widgetChinese->isVisible()) {
ui->widgetLetter->setVisible(false);
ui->widgetNumber->setVisible(false);
ui->widgetChinese->setVisible(true);
} else {
ui->widgetLetter->setVisible(true);
ui->widgetNumber->setVisible(false);
ui->widgetChinese->setVisible(false);
}
//重新设置图标
QString strMore = ui->widgetMore->isVisible() ? "up" : "down";
ui->labMore->setPixmap(QString(":/image/btn_%1_%2.png").arg(strMore).arg(iconType));
return true;
}
}
} else if (watched == ui->labType) {
if (event->type() == QEvent::MouseButtonPress) {
if (inputType == "english") {
setInputType("chinese");
} else if (inputType == "chinese") {
setInputType("english");
}
}
} else if (watched == ui->labType2) {
if (event->type() == QEvent::MouseButtonPress) {
setInputType("english");
}
} else if (watched == ui->widgetCn) {
//没有汉字或者按下的地方没有汉字或者当前汉字标签个数过少都不用继续
if (!labCn.first()->isEnabled() || lastText.isEmpty()) {
return false;
}
//记住最后按下拖动的时间,过短则认为是滑动,启动滑动动画
static bool pressed = false;
static QPoint lastPos = QPoint();
static QDateTime lastTime = QDateTime::currentDateTime();
QMouseEvent *mouseEvent = static_cast(event);
if (event->type() == QEvent::MouseButtonPress) {
pressed = true;
lastPos = mouseEvent->pos();
animationCn->stop();
lastTime = QDateTime::currentDateTime();
} else if (event->type() == QEvent::MouseButtonRelease) {
pressed = false;
if (lastPos != mouseEvent->pos()) {
//判断当前时间和鼠标按下事件比较,时间短则说明是滑动
QDateTime now = QDateTime::currentDateTime();
if (lastTime.msecsTo(now) < 600) {
//可以改变下面的值来调整幅度
bool moveleft = (mouseEvent->pos().x() - lastPos.x()) < 0;
int offset = moveleft ? 350 : -350;
int value = ui->scrollAreaCn->horizontalScrollBar()->value();
animationCn->setStartValue(value);
animationCn->setEndValue(value + offset);
animationCn->start();
}
}
} else if (event->type() == QEvent::MouseMove) {
if (pressed && labCn.first()->isEnabled()) {
//计算滑过的距离
bool moveleft = (mouseEvent->pos().x() - lastPos.x()) < 0;
int offset = moveleft ? 5 : -5;
int value = ui->scrollAreaCn->horizontalScrollBar()->value();
ui->scrollAreaCn->horizontalScrollBar()->setValue(value + offset);
return true;
}
}
} else if (watched == ui->widgetMore) {
//没有汉字或者按下的地方没有汉字或者当前汉字标签个数过少都不用继续
if (!labMore.first()->isEnabled() || lastText.isEmpty()) {
return false;
}
//记住最后按下拖动的时间,过短则认为是滑动,启动滑动动画
static bool pressed = false;
static QPoint lastPos = QPoint();
static QDateTime lastTime = QDateTime::currentDateTime();
QMouseEvent *mouseEvent = static_cast(event);
if (event->type() == QEvent::MouseButtonPress) {
pressed = true;
lastPos = mouseEvent->pos();
animationMore->stop();
lastTime = QDateTime::currentDateTime();
} else if (event->type() == QEvent::MouseButtonRelease) {
pressed = false;
if (lastPos != mouseEvent->pos()) {
//判断当前时间和鼠标按下事件比较,时间短则说明是滑动
QDateTime now = QDateTime::currentDateTime();
if (lastTime.msecsTo(now) < 600) {
//可以改变下面的值来调整幅度
bool movebottom = (mouseEvent->pos().y() - lastPos.y()) < 0;
int offset = movebottom ? 150 : -150;
int value = ui->scrollAreaMore->verticalScrollBar()->value();
animationMore->setStartValue(value);
animationMore->setEndValue(value + offset);
animationMore->start();
}
}
} else if (event->type() == QEvent::MouseMove) {
if (pressed && labMore.first()->isEnabled()) {
//计算滑过的距离
bool movebottom = (mouseEvent->pos().y() - lastPos.y()) < 0;
int offset = movebottom ? 5 : -5;
int value = ui->scrollAreaMore->verticalScrollBar()->value();
ui->scrollAreaMore->verticalScrollBar()->setValue(value + offset);
return true;
}
}
} else if (watched->inherits("QLabel")) {
QLabel *lab = (QLabel *)watched;
if (!upper && inputType == "chinese") {
if (lab->property("labCn").toBool()) {
//记住最后按下的滚动条位置,如果滚动条一直没有变化则认为单击了标签
static int lastPosition = 0;
if (event->type() == QEvent::MouseButtonPress) {
lastPosition = ui->scrollAreaCn->horizontalScrollBar()->value();
lastText = lab->text();
} else if (event->type() == QEvent::MouseButtonRelease) {
if (lastPosition == ui->scrollAreaCn->horizontalScrollBar()->value() && !lastText.isEmpty()) {
insertValue(lab->text());
clearChinese();
}
}
} else if (lab->property("labMore").toBool()) {
//记住最后按下的滚动条位置,如果滚动条一直没有变化则认为单击了标签
static int lastPosition = 0;
if (event->type() == QEvent::MouseButtonPress) {
lastPosition = ui->scrollAreaMore->verticalScrollBar()->value();
lastText = lab->text();
} else if (event->type() == QEvent::MouseButtonRelease) {
if (lastPosition == ui->scrollAreaMore->verticalScrollBar()->value() && !lastText.isEmpty()) {
insertValue(lab->text());
clearChinese();
}
}
}
}
} else {
if (event->type() == QEvent::MouseButtonPress) {
if (currentWidget != 0) {
if (!isVisible()) {
showPanel();
}
} else {
if (isVisible()) {
hidePanel();
}
}
}
}
return QWidget::eventFilter(watched, event);
}
void frmInput2019::initForm()
{
#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))
setWindowFlags(Qt::Tool | Qt::WindowDoesNotAcceptFocus | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
#else
setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
#endif
currentWidget = 0;
upper = false;
number = false;
onlyControl = false;
autoHide = false;
columnCount = 8;
maxCount = 256;
dbPath = qApp->applicationDirPath();
//绑定按钮到事件
QList btns;
btns << ui->widgetLetter->findChildren();
btns << ui->widgetNumber->findChildren();
foreach (QPushButton *btn, btns) {
btn->setProperty("btnInput", true);
connect(btn, SIGNAL(clicked()), this, SLOT(btnClicked()));
}
//设置字母属性
btns.clear();
btns << ui->widgetLetter1->findChildren();
btns << ui->widgetLetter2->findChildren();
foreach (QPushButton *btn, btns) {
btn->setProperty("btnLetter", true);
}
//设置所有按钮输入法不可用+长按自动重复事件
btns.clear();
btns << this->findChildren();
foreach (QPushButton *btn, btns) {
btn->setFocusPolicy(Qt::NoFocus);
btn->setProperty("noinput", true);
btn->setAutoRepeat(true);
btn->setAutoRepeatDelay(500);
}
//默认最大生成256个,添加到顶部滚动区域中
for (int i = 0; i < maxCount; i++) {
QLabel *lab = new QLabel;
lab->setProperty("labCn", true);
lab->setEnabled(false);
ui->layout->addWidget(lab);
labCn << lab;
}
//默认最大生成256个,添加到更多滚动区域中
int row = 0;
int column = 0;
for (int i = 0; i < maxCount; i++) {
QLabel *lab = new QLabel;
lab->setProperty("labMore", true);
lab->setEnabled(false);
lab->setAlignment(Qt::AlignCenter);
lab->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
ui->gridLayout->addWidget(lab, row, column);
labMore << lab;
column++;
if (column >= columnCount) {
row++;
column = 0;
}
}
ui->lab1->setEnabled(false);
ui->lab2->setEnabled(false);
ui->labPY->setEnabled(false);
ui->labMore->setEnabled(false);
//输入法面板的字体名称和按钮字体大小即汉字区域字体大小
setFontInfo(this->font().family(), 11, 10);
//图标固定大小
setIconSize(20, 20);
//按钮之间的间隔
setSpacing(6);
//顶部汉字区域高度
setTopHeight(40);
//输入法面板的显示位置 control--显示在对应输入框的正下方 bottom--填充显示在底部 center--窗体居中显示
setPosition("control");
//输入法模式 english--英文模式 chinese--中文模式 number--数字特殊字符模式
setInputType("english");
//输入法面板的样式 black--黑色 blue--淡蓝色 brown--灰黑色 gray--灰色 silvery--银色
setStyleName("black");
//定义动画产生平滑数值
animationCn = new QPropertyAnimation(ui->scrollAreaCn->horizontalScrollBar(), "value");
animationCn->setEasingCurve(QEasingCurve::OutCirc);
animationCn->setDuration(500);
animationMore = new QPropertyAnimation(ui->scrollAreaMore->verticalScrollBar(), "value");
animationMore->setEasingCurve(QEasingCurve::OutCirc);
animationMore->setDuration(500);
}
void frmInput2019::init()
{
if (onlyControl) {
ui->labPY->setVisible(false);
this->installEventFilter(this);
ui->labType->installEventFilter(this);
ui->labType2->installEventFilter(this);
ui->labMore->installEventFilter(this);
ui->widgetCn->installEventFilter(this);
ui->widgetMore->installEventFilter(this);
foreach (QLabel *lab, labCn) {
lab->installEventFilter(this);
}
foreach (QLabel *lab, labMore) {
lab->installEventFilter(this);
}
} else {
//绑定全局改变焦点信号槽
connect(qApp, SIGNAL(focusChanged(QWidget *, QWidget *)), this, SLOT(focusChanged(QWidget *, QWidget *)));
qApp->installEventFilter(this);
}
py.open(dbPath);
readChinese();
}