QT自定义软键盘

效果图:

QT自定义软键盘_第1张图片

项目中需要用到软键盘, 最初的时候,打算使用QT自带的软键盘, 但苦于不会QML, 再加上, 项目中的二级界面都是用的模态窗, QT自带软键盘不能输入。

不得已, 打算自己写一个。 好在项目不需要太复杂的输入, 主要是参数这些

先是找到了一个例子

https://blog.csdn.net/wzs250969969/article/details/78418725

大概是这样的

QT自定义软键盘_第2张图片

但这个例子我运行的时候, 关闭按钮关不掉, 并且按钮这些都是手写的, 所以没法直观的进行修改, 因此参考了他的核心代码, 写了一个简单的软键盘出来, 并且用到了一些图片, 使得软键盘好看了点

在使用的时候, 只需要在主函数中创建一个对象即可

MyKeyBoard keybord;

MyKeyBoard.h

#ifndef MYKEYBOARD_H
#define MYKEYBOARD_H

#include 
#include 
#include 


namespace Ui {
class MyKeyBoard;
}

class MyKeyBoard : public QDialog
{
    Q_OBJECT

public:
    explicit MyKeyBoard(QWidget *parent = nullptr);
    ~MyKeyBoard();

private slots:
    void btn_click(); //按钮被点击事件
    bool eventFilter(QObject *obj, QEvent *e);
private:
    Ui::MyKeyBoard *ui;

    void init(); //初始化, 进行所有按钮的事件绑定

private:
    QLineEdit *currentLineEdit;     //当前焦点的文本框
    QString currentType;            //当前输入法类型
    bool mousePressed;                //是否按下


    int deskWidth; //屏幕宽度高度, 以及自身宽度高度
    int deskHeight;
    int frmWidth;
    int frmHeight;
    int _cur_pos;  //编辑框中, 当前光标的位置
    bool is_exit; //是否要退出 如果是true则表示要退出;
    /*窗口移动*/
protected:
    void mousePressEvent(QMouseEvent *e);
    void mouseMoveEvent(QMouseEvent *e);
    void mouseReleaseEvent(QMouseEvent *e);
private:
    bool _is_down;
    QPoint _point;
};

#endif // MYKEYBOARD_H

 

MyKeyBoard.cpp

#include "mykeyboard.h"
#include "ui_mykeyboard.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 


MyKeyBoard::MyKeyBoard(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::MyKeyBoard)
{
    ui->setupUi(this);
    this->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint); //Qt::WindowStaysOnTopHint |
    ui->btn_move->setAttribute( Qt::WA_TransparentForMouseEvents, true );

    ui->btn_close->setIcon( QIcon(":/image/icon/close.png") );
    ui->btn_move->setIcon( QIcon(":/image/icon/move.png") );
    ui->btn_del->setIcon( QIcon(":/image/icon/backspace.png") );
    ui->btn_enter->setIcon( QIcon(":/image/icon/enter.png") );
    ui->btn_space->setIcon( QIcon(":/image/icon/space.png") );
    ui->btn_clear->setIcon( QIcon(":/image/icon/clear.png") );


    deskWidth =  QApplication::desktop()->width();
    deskHeight = QApplication::desktop()->height();
    frmWidth = this->width();
    frmHeight = this->height();

    is_exit = false;
    init();



}

MyKeyBoard::~MyKeyBoard()
{
    delete ui;
}


/*实现窗口移动*/
void MyKeyBoard::mousePressEvent(QMouseEvent *e)
{
    if(e->button() != Qt::LeftButton)
        return;
    int x = ui->btn_move->x();
    int y = ui->btn_move->y();
    int rx = ui->btn_move->width();
    int ry = ui->btn_move->height();
    int cur_x = e->pos().x();
    int cur_y = e->pos().y();
    if(cur_x>x && cur_y>y && cur_xglobalPos();
    }

}
void MyKeyBoard::mouseMoveEvent(QMouseEvent *e)
{
    if(_point.isNull())
        return;

    if(_is_down)
    {
        QPoint n_pos = e->globalPos();
        QPoint update_pos = mapToParent(n_pos - _point);
        move(update_pos);
        _point = n_pos;
    }

}
void MyKeyBoard::mouseReleaseEvent(QMouseEvent *)
{
    _is_down = false;
}
/***********/



void MyKeyBoard::btn_click()
{
        QPushButton *btn = (QPushButton *)sender();
        QString objectName = btn->objectName();

        if (objectName == "btn_del")
        {
            if (currentLineEdit != nullptr) //点击删除
            {
                ui->_key_board_input_lineedit->backspace();
                currentLineEdit->setText( ui->_key_board_input_lineedit->text() );  //这里是因为, 点击删除的时候, 有可能是删除了选中的多个文本, 如果也用backspace的话, 会导致2个编辑框文本不一致
            }
        }
        else if (objectName == "btn_close") //点击关闭窗口
        {
            is_exit = true;
            currentLineEdit->setText( ui->_key_board_input_lineedit->text() );
            currentLineEdit->setFocusPolicy(Qt::ClickFocus);
            this->close();
        }
        else if(objectName == "btn_enter") //点击回车
        {
            currentLineEdit->setText( ui->_key_board_input_lineedit->text() );
            QKeyEvent enterkey(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
            QCoreApplication::sendEvent( currentLineEdit, &enterkey );
            this->close();
        }
        else if(objectName == "btn_space")  //按下空格
        {
            if (currentLineEdit != nullptr)
            {
                currentLineEdit->insert(" ");
                ui->_key_board_input_lineedit->insert( " " );
            }
        }
        else if(objectName == "btn_clear") //按下清空
        {
            if (currentLineEdit != nullptr)
            {
                currentLineEdit->setText("");
                ui->_key_board_input_lineedit->setText("");
            }
        }
        else
        {
            QString value = btn->text();
            //当前的焦点是编辑框, 那么就插入一个字符
            if (currentLineEdit != nullptr)
            {
                ui->_key_board_input_lineedit->insert(value);
                currentLineEdit->setText( ui->_key_board_input_lineedit->text() );
                if(ui->_key_board_input_lineedit != nullptr)
                {
                    currentLineEdit->setCursorPosition( ui->_key_board_input_lineedit->cursorPosition() );
                }
            }
        }
}


//这个被放弃了, 现在使用事件过滤器的方式
void MyKeyBoard::focus_changed(QWidget *, QWidget *nowWidget)
{

    if (nowWidget != 0 && !this->isAncestorOf(nowWidget))
    {
        if (nowWidget->inherits("QLineEdit"))
        {
            currentLineEdit = (QLineEdit *)nowWidget;
            QPoint movePoint;

            // 鼠标点击位置坐标
            if (QCursor::pos().y() > deskHeight / 2)
            {
                // 靠上居中显示
                movePoint = QPoint(deskWidth/2 - frmWidth/2, 0);
            }
            else
            {
                // 靠下居中显示
                movePoint = QPoint(deskWidth/2 - frmWidth/2, deskHeight - frmHeight);
            }
            this->move(movePoint);
            this->repaint();

            if(!is_exit)
            {
                this->exec();
            }
            else {
                is_exit = false;
                this->close();
            }
        }
        else if(nowWidget->inherits("QComboBox"))
        {
            currentLineEdit = static_cast(nowWidget)->lineEdit() ;

            if(!is_exit)
            {
                is_exit = true;
                this->exec();
            }
            else {
                is_exit = false;
                this->close();
            }
        }
        else
        {
            currentLineEdit = nullptr;
            this->close();

        }
    }


}

bool MyKeyBoard::eventFilter(QObject *obj, QEvent *e)
{

   if(obj->metaObject()->className() == QStringLiteral("QLineEdit"))
   {
       QLineEdit *tmp_edit = static_cast< QLineEdit* >(obj); //第一步判断
       if(tmp_edit->objectName() == "_key_board_input_lineedit") //如果点击的是自己自带的编辑框的话, 那就是要修改光标位置了
       {
           QMouseEvent *mEvent = static_cast< QMouseEvent* >(e);
           if(mEvent->button() == Qt::LeftButton)
           {
                if(tmp_edit != nullptr)
                {
                    _cur_pos = ui->_key_board_input_lineedit->cursorPosition();
                    currentLineEdit->setCursorPosition( _cur_pos );
                }
           }
           return false;
       }


       QLineEdit *edit = static_cast< QLineEdit* >(obj);
       if(e->type() == QEvent::MouseButtonPress && edit->isEnabled())
       {
           currentLineEdit = (QLineEdit *)obj;
           ui->_key_board_input_lineedit->setText( currentLineEdit->text() );
           ui->_key_board_input_lineedit->setCursorPosition( currentLineEdit->cursorPosition() );
           QPoint movePoint = QCursor::pos();
           this->move( movePoint.x(), movePoint.y()+edit->height() );
           this->repaint();
           this->exec();
       }
   }


}

void MyKeyBoard::init()
{
    currentLineEdit = 0;
    mousePressed = false;
    currentType = "min";

    QList btn = this->findChildren();
    foreach (QPushButton * b, btn) {
        connect(b, SIGNAL(clicked()), this, SLOT(btn_click()));
    }

    qApp->installEventFilter(this);

}

很多代码都是用的上边的参考例子, 修改了布局, 以及模态输入, 和实现逻辑。使用还是很方便的。

这套软键盘的配色也很简单, 只需要几行css即可

#_key_board_input_lineedit{
    border: 1px solid rgb(155,155,155);
    background:rgb(28,29,30);
    border-radius:2px;
    font-size:20px;
    color:rgb(230,230,230);
}
/*软键盘的CSS*/
#MyKeyBoard{
background:rgb(28,29,30);
}


.MyKeyBoard QPushButton{
    border-radius:1px;
    text-align:center;
    background:rgb(48,50,50);
    margin:1px;
    font-size:22px;
    color:rgb(255,255,255);
}
.MyKeyBoard QPushButton:enabled:hover{
    background:rgb(48,50,50);
}
.MyKeyBoard QPushButton:enabled:pressed{
    background:rgb(60,60,60);
}

主要代码全在这里了。 ui文件可以自己对应着拖一个好看的出来

 

 

 

你可能感兴趣的:(QT随笔,QT,软键盘)