Qt实现自定义QDoubleSpinBox软键盘

news2024/11/17 11:49:37

在Qt应用程序开发中,经常会遇到需要自定义输入控件的需求。其中,对于QDoubleSpinBox控件,如果希望在点击时弹出一个自定义的软键盘,以便用户输入数值,并将输入的值设置给QDoubleSpinBox,该如何实现呢?

在本文中,我们将介绍如何使用Qt框架,结合自定义的软键盘,实现一个可以在QDoubleSpinBox控件下方弹出的数字输入解决方案。我们将从头开始构建这个功能,并逐步引导您完成实现过程。

首先,我们将创建一个名为CustomDoubleSpinBox的自定义控件,它是QDoubleSpinBox的子类。我们将重写focusInEvent函数,该函数在QDoubleSpinBox获取焦点时被调用。在这个函数中,我们将创建并显示我们自己设计的软键盘CustomKeyboard,并确保它在QDoubleSpinBox的下方弹出。

接着,我们将继续创建CustomKeyboard类,它是一个继承自QWidget的自定义控件。在CustomKeyboard中,我们将实现一个数字键盘,允许用户输入数字,并在确认后返回输入的数值。

#ifndef CUSTOMKEYBOARD_H
#define CUSTOMKEYBOARD_H

#include <QObject>
#include <QWidget>
#include <QDebug>
#include <QLabel>
#include <QGridLayout>
#include <QPushButton>
#include <QDebug>

class CustomKeyboard : public QWidget
{
    Q_OBJECT

    public:
        explicit CustomKeyboard(QWidget *parent = nullptr);
        double getValue() const;

    signals:
        void confirmed(double);

    private:
        QString currentValue;
        QLabel *m_pCurrentLab;

    private slots:
        void on_digitButton_clicked();
        void on_decimalButton_clicked();
        void on_backspaceButton_clicked();
        void on_clearButton_clicked();
        void on_confirmButton_clicked();
        void on_closeButton_clicked();
    };

#endif // CUSTOMKEYBOARD_H

#include "customkeyboard.h"

CustomKeyboard::CustomKeyboard(QWidget *parent) : QWidget(parent)
{
    this->setWindowFlag(Qt::FramelessWindowHint);
    QVBoxLayout *layout = new QVBoxLayout;
        currentValue = "";
        m_pCurrentLab = new QLabel();

        QGridLayout *gridLayout = new QGridLayout;
        gridLayout->addWidget(m_pCurrentLab,0,0,1, 3);
        m_pCurrentLab->setStyleSheet("color:black");
        for (int i = 0; i <= 9; ++i)
        {
            QPushButton *digitButton = new QPushButton(QString::number(i));
            connect(digitButton, &QPushButton::clicked, this, &CustomKeyboard::on_digitButton_clicked);
            if(i == 9)
            {
                gridLayout->addWidget(digitButton, 4, 1);
            }
            else
                gridLayout->addWidget(digitButton, i / 3 +1, i % 3+1);
        }

        QPushButton *decimalButton = new QPushButton(".");
        connect(decimalButton, &QPushButton::clicked, this, &CustomKeyboard::on_decimalButton_clicked);
        gridLayout->addWidget(decimalButton, 4, 2);

        QPushButton *backspaceButton = new QPushButton("Backspace");
        connect(backspaceButton, &QPushButton::clicked, this, &CustomKeyboard::on_backspaceButton_clicked);
        gridLayout->addWidget(backspaceButton, 5, 2);

        QPushButton *clearButton = new QPushButton("Clear");
        connect(clearButton, &QPushButton::clicked, this, &CustomKeyboard::on_clearButton_clicked);
        gridLayout->addWidget(clearButton,4, 3);

        QPushButton *confirmButton = new QPushButton("Confirm");
        connect(confirmButton, &QPushButton::clicked, this, &CustomKeyboard::on_confirmButton_clicked);
        gridLayout->addWidget(confirmButton, 5, 1, 1, 1);

        QPushButton *closeButton = new QPushButton("Close");
        connect(closeButton, &QPushButton::clicked, this, &CustomKeyboard::on_closeButton_clicked);
        gridLayout->addWidget(closeButton, 5, 3, 1, 1);

        layout->addLayout(gridLayout);
        setLayout(layout);


        this->setStyleSheet("QLabel{font: 22px;color:white;}\
                            QPushButton{background-color:rgb(42, 49, 66);border: 1px solid rgb(206,206,206);border-radius: 5px;font:18px;Min-width:112px;Max-width:112px;Min-height:35px;color:white}\
                            QPushButton:hover{background-color:rgb(210,210,210);}\
                            QPushButton:pressed{background-color:rgb(160,160,160);}");
    }

    double CustomKeyboard::getValue() const
    {
        return currentValue.toDouble();
    }

    void CustomKeyboard::on_digitButton_clicked()
    {
        QPushButton *clickedButton = qobject_cast<QPushButton*>(sender());
        currentValue += clickedButton->text();
        m_pCurrentLab->setText(currentValue);
    }

    void CustomKeyboard::on_decimalButton_clicked()
    {
        if (!currentValue.contains('.'))
        {
            currentValue += '.';
        }
         m_pCurrentLab->setText(currentValue);
    }

    void CustomKeyboard::on_backspaceButton_clicked()
    {
        currentValue.chop(1);
         m_pCurrentLab->setText(currentValue);
    }

    void CustomKeyboard::on_clearButton_clicked()
    {
        currentValue = "0";
         m_pCurrentLab->setText(currentValue);
    }

    void CustomKeyboard::on_confirmButton_clicked()
    {
        emit confirmed(getValue());
    }

    void CustomKeyboard::on_closeButton_clicked()
    {
        this->close();
        this->deleteLater();
    }

在完成这两个自定义控件的设计后,我们将把它们组合在一起,实现自定义的QDoubleSpinBox软键盘功能。当用户点击QDoubleSpinBox控件时,我们的自定义软键盘将弹出,并在用户输入数字后自动设置给QDoubleSpinBox,使整个输入流程更加便捷和友好。

// customdoublespinbox.h

#ifndef CUSTOMDOUBLESPINBOX_H
#define CUSTOMDOUBLESPINBOX_H

#include <QDoubleSpinBox>
#include "customkeyboard.h"

class CustomDoubleSpinBox : public QDoubleSpinBox
{
    Q_OBJECT

public:
    explicit CustomDoubleSpinBox(QWidget *parent = nullptr);

protected:
    void focusInEvent(QFocusEvent *event) override;

private:
    CustomKeyboard *keyboard;
};

#endif // CUSTOMDOUBLESPINBOX_H
// customdoublespinbox.cpp

#include "customdoublespinbox.h"
#include <QFocusEvent>
#include <QApplication>
#include <QDesktopWidget>

CustomDoubleSpinBox::CustomDoubleSpinBox(QWidget *parent) : QDoubleSpinBox(parent)
{
    // 初始化成员变量
    keyboard = nullptr;
}

void CustomDoubleSpinBox::focusInEvent(QFocusEvent *event)
{
    // 在QDoubleSpinBox获取焦点时弹出软键盘
    if (keyboard == nullptr)
    {
        // 获取主屏幕的尺寸
        QRect primaryScreenRect = QApplication::primaryScreen()->geometry();

        // 创建一个 CustomKeyboard 实例
        keyboard = new CustomKeyboard(this);
        connect(keyboard, &CustomKeyboard::confirmed, [this]() {
            // 从 CustomKeyboard 获取输入的值并设置给 QDoubleSpinBox
            double value = this->valueFromText(QString::number(keyboard->getValue()));
            this->setValue(value);
            keyboard->deleteLater(); // 关闭软键盘
        });

        // 将 CustomKeyboard 设置为 QDoubleSpinBox 的特殊键盘
        this->setSpecialValueText(" ");
        this->setKeyboardTracking(false);

        // 获取 QDoubleSpinBox 在主窗口中的位置
        QPoint spinBoxPos = this->mapToGlobal(QPoint(0, this->height()));

        // 设置 CustomKeyboard 在 QDoubleSpinBox 下方弹出
        keyboard->move(spinBoxPos.x(), spinBoxPos.y());
        keyboard->show();
    }

    QDoubleSpinBox::focusInEvent(event);
}

通过本文的介绍和示例代码,您将学会如何在Qt应用程序中实现自定义的QDoubleSpinBox软键盘功能。这将为您的应用程序带来更好的用户体验,并增加交互性。如果您对此功能感兴趣,可以参考本文提供的示例代码,并将其应用于您自己的项目中。

 

希望本文对您有所帮助,并且能够在Qt应用程序开发中为您带来更多灵活、个性化的控件定制体验。如果您有任何问题或建议,欢迎在评论区留言,我们将竭诚为您解答。谢谢阅读!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/831731.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

35.利用fminsearch解 多元变量无约束条件下的函数最小值(matlab程序)

1.简述 1.fminsearch函数基本语法 函数功能&#xff1a;使用无导数法计算无约束多变量函数的最小值 语法 x fminsearch(fun,x0) x fminsearch(fun,x0,options) x fminsearch(problem) [x,fval] fminsearch(___) [x,fval,exitflag] fminsearch(___) [x,fval,exitflag,out…

苹果、高通、联发科新一代旗舰处理器纷纷出炉,A17 又赢麻了

眼看又到了 8 月份&#xff0c;距离每年后半段各家新款旗舰手机发布的日子越来越近。 但在这之前往往率先展开的是移动手机处理器之间的巅峰对决。 高通骁龙 8 Gen3、联发科天玑 9300、苹果 A17 无疑将会成为今年厮杀的主战场。 到了临近关头&#xff0c;这几款处理器规格、性…

如何制作一个中小学分班查询系统?

随着暑假接近尾声&#xff0c;新学年即将开始&#xff0c;学校面临着重要的任务&#xff0c;即学生们的分班问题。这一问题包括新生入学的分班及低年级学生升入高年级的分班。对负责分班工作的老师们来说&#xff0c;这无疑增加了工作量和挑战。 为确保学生顺利入学并分配到适…

url编码,html编码,uncode编码

目录 url编码 html实体编码 unicode编码 url编码 URL编码遵循下列规则&#xff1a; 每对name/value由&&#xff1b;符分开&#xff1b;每对来自表单的name/value由符分开。如果用户没有输入值给这个name&#xff0c;那么这个name还是出现&#xff0c;只是无值。任何特殊…

【复习61-66题】【每天40分钟,我们一起用50天刷完 (剑指Offer)】第四十四天 44/50

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

KEIL Map文件解析以及如何从Map文件还原内存分布

一、什么是Map文件 简单来说&#xff0c;Map文件是编译器编译工程后生成的一个文件&#xff0c;这个文件反映了各个源文件生成的模块间的交叉引用、移除的未使用模块、符合映射表、内存映射以及各个模块的大小和汇总数据等。 所以说&#xff0c;当你在遇到或怀疑存在内存越界或…

RISC-V基础之函数调用(三)保留寄存器(包含实例)

RISC-V将寄存器分为保留和非保留两类。保留寄存器是指在函数调用前后必须保持相同值的寄存器&#xff0c;因为调用者期望在调用后能够继续使用这些寄存器的值。保留寄存器包括s0到s11&#xff08;因此称为saved&#xff09;&#xff0c;sp和ra。非保留寄存器&#xff0c;也称为…

2023年华数杯B题

B 题 不透明制品最优配色方案设计 日常生活中五彩缤纷的不透明有色制品是由着色剂染色而成。因此&#xff0c;不透明 制品的配色对其外观美观度和市场竞争力起着重要作用。然而&#xff0c;传统的人工配色 存在一定的局限性&#xff0c;如主观性强、效率低下等。因此&#xff0…

uniapp封装request请求

在基础文件里面创建一个api文件 在创建两个 js文件 http.js 里面封装 request 请求 let baseUrl https://white.51.toponet.cn; //基地址 export const request (options {}) > {//异步封装接口&#xff0c;使用Promise处理异步请求return new Promise((resolve, reject…

html学习7(iframe)

1、通过使用iframe标签定义框架&#xff0c;可在同一个浏览器中显示不止一个画面。 2、height和width属性用于定义框架的高度与宽度。 3、属性frameborder‘0’用于是否显示边框。 4、iframe可以显示一个目标链接的页面&#xff0c;链接的target属性设置为相应的iframe名称。…

【无网络】win10更新后无法联网,有线无线都无法连接,且打开网络与Internet闪退

win10更新后无法联网&#xff0c;有线无线都无法连接&#xff0c;且打开网络与Internet闪退 法1 重新配置网络法2 更新驱动法3 修改注册表编辑器法4 重装系统 自从昨晚点了更新与重启后&#xff0c;今天电脑就再也不听话了&#xff0c;变着花样地连不上网。 检查路由器&#xf…

win10笔记本显示器根据页面显示亮度自动调节亮度的问题

系统是win10企业版&#xff0c;针对这个问题查了很多种方法&#xff0c;比如&#xff1a; 1、控制面板->硬件和声音->电源选项->点击当前电源计划的更改计划设置->更改高级电源设置->显示->启用自适应亮度 但是我发现我的电源计划只有平衡这一种&#xff0c…

Linux系统jenkins+newman+postman持续集成环境搭建

1、首先安装nodejs 下载nodejs压缩包&#xff0c;下载地址&#xff1a;nodejs官网下载 建议不用下载最新的&#xff0c;我这里用的是推荐的v12.18版本 下载和解压命令 wget https://nodejs.org/dist/v12.18.3/node-v12.18.3-linux-x64.tar.xz解压安装包&#xff08;记得没有z&…

基于Kubernetes环境的高扩展机器学习部署利器——KServe

随着ChatGPT的发布&#xff0c;人们越来越难以回避利用机器学习的相关技术。从消息应用程序上的文本预测到智能门铃上的面部识别&#xff0c;机器学习&#xff08;ML&#xff09;几乎可以在我们今天使用的每一项技术中找到。 如何将机器学习技术交付给消费者是企业在开发过程中…

使用cmd查看3568主板相关

主要是说清楚思路的 rk3568主板能运行的程序都在system/bin里面&#xff0c;这个是我们直接可以使用cmd用到的 所以&#xff0c;往后我们想通过cmd了解RK3568的某一项参数的时候&#xff0c;或者想使用RK3568某一个系统功能的时候。应该先去system/bin里面查找对应的系统程序。…

Jenkins配置测试报告后无法正常显示或显示空白 的解决方法(问题集锦)

Jenkins配置测试报告后无法正常显示或显示空白&#xff1f; 现象1&#xff1a;界面样式错乱原因分析临时策略永久策略 现象2&#xff1a;报告路径不存在原因分析解决策略 现象3&#xff1a;docker和操作系统版本不匹配原因分析解决策略 现象1&#xff1a;界面样式错乱 打开报告…

实验笔记之——apk生成

最近拾回Android开发&#xff08;实验笔记之——Windows下的Android环境开发搭建_gwpscut的博客-CSDN博客&#xff09;&#xff0c;花了两天时间&#xff0c;写了个二维码识别的app 忘记如何生成apk了&#xff0c;写个笔记来记录一下 需要创建一下 对应的设置好 这里勾选上记住…

系统保留分区被误删怎么办?

当您在全新的磁盘上安装Windows时&#xff0c;将在磁盘的开头创建一个名系统保留的分区&#xff0c;大小约为100MB&#xff0c;然后是系统驱动器&#xff0c;然后是其他的驱动器。通常&#xff0c;系统保留分区在Windows 8中为350MB&#xff0c;在Windows 10中为500MB。系统保留…

网络安全(黑客)自学就业

前段时间&#xff0c;遇到网友提问&#xff0c;说为什么我信息安全专业的找不到工作&#xff1f; 造成这个结果主要是有两大方面的原因。 第一个原因&#xff0c;求职者本身的学习背景问题。那这些问题就包括学历、学校学到的知识是否扎实&#xff0c;是否具备较强的攻防实战…

webpack基础知识三:说说webpack中常见的Loader?解决了什么问题?

一、是什么 loader 用于对模块的"源代码"进行转换&#xff0c;在 import 或"加载"模块时预处理文件 webpack做的事情&#xff0c;仅仅是分析出各种模块的依赖关系&#xff0c;然后形成资源列表&#xff0c;最终打包生成到指定的文件中。如下图所示&#…