【Qt】从开源项目QCAD中学习如何增强QLineEdit控件

news2024/9/23 3:33:08

1 背景

Qt5 中有个很基本的单行输入框控件,就是 QLineEdit,类似于HTML中的input标签。

在QCAD开源项目中,其主界面中有个供用户输入绘图命令的单行输入框控件,其可以实现类似 Linux 终端的简单效果:

  1. 上键显示最近的一条命令
  2. 上下键在历史命令里面查找命令
  3.  Ctrl+V键粘贴命令
  4.  Ctrl+L键清空命令

功能简单,但是也算是看到了 Qt 的较中级的用法,就是继承和扩展Qt 原生组件。

2 代码说明

首先继承 QLineEdit 类。

新增了两个字段/属性,用于存储命令的字符串列表 history,还有一个迭代器 it,指代命令在列表中的位置。

重载 keyPressEvent 函数,用于支持自定义的Up,Down,Ctrl+V,Ctrl+L按键事件。

注意:源代码非完整代码,无法运行。

3 源代码

3.1 头文件 RCommandLine.h

/**
 * Copyright (c) 2011-2018 by Andrew Mustun. All rights reserved.
 * 
 * This file is part of the QCAD project.
 *
 * QCAD is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * QCAD is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with QCAD.
 */

#ifndef RCOMMANDLINE_H_
#define RCOMMANDLINE_H_

#include "gui_global.h"

#include <QEvent>
#include <QLineEdit>
#include <QMetaType>
#include <QStringList>

/**
 * \scriptable
 * \ingroup gui
 */
class QCADGUI_EXPORT RCommandLine: public QLineEdit {

Q_OBJECT

signals:
    void clearHistory();
    void commandConfirmed(const QString& command);
    void completeCommand(const QString& command);
    void escape();

public:
    RCommandLine(QWidget* parent = 0);
    QString getLastCommand();
    void appendCommand(const QString& cmd);
    QStringList getHistory() const;
    void setHistory(QStringList& h);
    void triggerCommand(const QString& cmd) {
        emit commandConfirmed(cmd);
    }

public slots:
    void paste();

protected:
    virtual void keyPressEvent(QKeyEvent* event);
    virtual bool event(QEvent* event);

private:
    QStringList history;
    QStringList::iterator it;
};

Q_DECLARE_METATYPE(RCommandLine*)

#endif

3.2  RCommandLine.cpp

/**
 * Copyright (c) 2011-2018 by Andrew Mustun. All rights reserved.
 * 
 * This file is part of the QCAD project.
 *
 * QCAD is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * QCAD is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with QCAD.
 */
#include <QClipboard>
#include <QDebug>
#include <QEvent>
#include <QKeyEvent>

#if QT_VERSION >= 0x050000
  #include <QGuiApplication>
#else
  #include <QApplication>
#endif

#include "RCommandLine.h"
#include "RDebug.h"

RCommandLine::RCommandLine(QWidget* parent) :
    QLineEdit(parent), it(history.end()) {
}

QString RCommandLine::getLastCommand() {
    if (history.isEmpty()) {
        return QString();
    }
    return history.last();
}

void RCommandLine::appendCommand(const QString& cmd) {
    if (!cmd.isEmpty() && (history.isEmpty() || history.last() != cmd)) {
        history.append(cmd);
    }
    it = history.end();
}

QStringList RCommandLine::getHistory() const {
    return history;
}

void RCommandLine::setHistory(QStringList& h) {
    history = h;
    it = history.end();
}

void RCommandLine::paste() {
#if QT_VERSION >= 0x050000
    QClipboard* cb = QGuiApplication::clipboard();
#else
    QClipboard* cb = QApplication::clipboard();
#endif
    //qDebug("pasting: " + cb.text());

    QString text = cb->text();

    // multi line paste and enter:
    if (text.contains("\n")) {
        QStringList lines = text.split('\n');
        for (int i=0; i<lines.length(); i++) {
            //qDebug("line: " + lines[i]);
            emit commandConfirmed(lines[i]);
        }
    }
    else {
        // single line paste only:
        QLineEdit::paste();
    }
}

bool RCommandLine::event(QEvent* event) {
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent* ke = dynamic_cast<QKeyEvent*> (event);
        if (ke->key() == Qt::Key_Tab) {
            emit completeCommand(text());
            return true;
        }
    }
    return QLineEdit::event(event);
}

void RCommandLine::keyPressEvent(QKeyEvent* event) {
    switch (event->key()) {
    case Qt::Key_L:
        if (event->modifiers() == Qt::ControlModifier) {
            emit clearHistory();
            return;
        }
        break;
    case Qt::Key_V:
        if (event->modifiers() == Qt::ControlModifier) {
            paste();
            return;
        }
        break;
    case Qt::Key_Enter:
    case Qt::Key_Return: {
        QString t = text();
//        if (!t.isEmpty() && (history.isEmpty() || history.last() != t)) {
//            history.append(t);
//        }
        it = history.end();
        emit commandConfirmed(t);
        }
        break;
    case Qt::Key_Up:
        if (it != history.begin()) {
            it--;
            setText(*it);
        }
        return;
        break;
    case Qt::Key_Down:
        if (it != history.end()) {
            it++;
            if (it != history.end()) {
                setText(*it);
            } else {
                clear();
            }
        }
        return;
        break;
    default:
        break;
    }
    QLineEdit::keyPressEvent(event);
}

以上源代码仅供学习交流,版权归QCAD项目所有。

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

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

相关文章

基于jsp+ssm的家政服务系统-计算机毕业设计

项目介绍 作为一个家政服务系统&#xff0c;它就面对着许多用户的操作&#xff0c;而这些用户对系统的操作应该有所不同&#xff0c;所以我们在设计时必须要对不同的用户设立不同的的权限在本系统中&#xff0c;我考虑了3种权限&#xff08;管理员&#xff0c;雇主&#xff0c…

盘点JDK中基于CAS实现的原子类

前言 JDK中提供了一系列的基于CAS实现的原子类&#xff0c;CAS 的全称是Compare-And-Swap&#xff0c;底层是lock cmpxchg指令&#xff0c;可以在单核和多核 CPU 下都能够保证比较交换的原子性。所以说&#xff0c;这些原子类都是线程安全的&#xff0c;而且是无锁并发&#x…

国内设计师经常逛的5个素材网站

设计师必备的5个设计素材网站&#xff0c;免费下载&#xff0c;还可商用&#xff0c;再也不用担心侵权了。1、菜鸟图库 https://www.sucai999.com/?vNTYwNDUx菜鸟图库是一个素材量非常丰富的网站&#xff0c;网站聚合了平面、UI、淘宝电商、高清背景图、图片、插画等高质量素材…

六 游戏基础知识和SHAPE

显示对象 在Egret渲染架构设计中&#xff0c;我们将能够参与渲染的对象抽象为显示对象 Egret引擎中所有的显示对象类型表格&#xff1a; 坐标系 egret游戏中的的坐标原点位于舞台的左上角 显示列表与容器类 所有的容器全部继承于 DisplayObjectContainer类 DisplayObje…

世界杯主题系列-用Scratch制作足球比赛小游戏,源码分享啦

目录 一&#xff1a;两个小游戏的预览图效果图&#xff1a; 二&#xff1a;简单版双人足球赛源码&#xff1a; 三&#xff1a;复杂多人控制版足球赛源码 先来动态gif效果图&#xff1a; 四年一度的世界杯正在卡塔尔火热进行中&#xff01; 在绿茵场内&#xff0c;有胜利的…

Reids实战——分布式锁优化(Lua脚本)

1 基于Redis分布式锁的问题 先来看看之前分布式锁的实现。 这个基于Redis的分布式锁仍然有着一个问题&#xff0c;那就是误删锁的问题。 简单的来说&#xff0c;就是当第一个线程&#xff0c;也就是线程1&#xff0c;拿到锁后&#xff0c;但由于本身业务复杂&#xff0c;而导…

gvim写verilog环境搭建——将文本编辑器客制化定义为你自己的IDE

本文将详细描述将vim变成写Verilog代码的IDE客制化的实现过程&#xff0c;同时最后提供自己的环境。实现的过程中有使用自己写的&#xff0c;也有参考借鉴其他同学进行一定的修改&#xff0c;也有直接使用插件实现的相关功能。对应的功能实现部分均会给出相应的参考与插件地址等…

基于jsp+ssm的网上图书商城-计算机毕业设计

项目介绍 本系统的用户群体分为管理员、会员两类。不同的身份拥有不同的职责和权限。管理员的职能包括&#xff1a;图书管理、会员管理、订单信息审核、个人信息维护等 该网上书城系统应该具备有图书添加、图书信息修改、用户浏览图书、用户搜索图书、图书购买和订购等功能&a…

为什么在高速PCB设计当中信号线不能多次换孔

大家在进行PCB设计时过孔肯定是要接触的&#xff0c;那么大家知道过孔对于我们PCB的信号质量影响有多大吗&#xff1f; 在搞清楚上面这个这个问题之前我们先给大家介绍一下我们在PCB设计时过孔应该如何选取。 一般过孔种类有以下三种可以进行选择&#xff1a;&#xff08;单位是…

00后会不会改变软件测试行业现状?

不可置否&#xff0c;从年开始&#xff0c;00后开始进入职场&#xff0c;开始他们漫长的职业生涯啦。 作为经历过90后改变职场规则的80后的老人们&#xff0c;又要瑟瑟发抖啦。 因为在90后之后&#xff0c;00后又开始整顿职场了。 80后&#xff0c;上有老下有小&#xff0c;为…

纪念DedeCMS创始人IT柏拉图先生

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; IT柏拉图开发了DedeCMS&#xff0c;造福了千万站长&#xff0c;但却没有因为这套系统过上体面的生活。 &#xff08;图片取自IT柏拉图的新浪微博&#xff09; 1979年你出生了&#xff0c;比我大…

【刷题心得】双指针法|HashSet<T>

题目 1 概念梳理 1.1 ISet<T> HashSet<T> 包含不重复元素的集合称为“集set”。.NET Framework包含两个集HashSet<T>和SortedSet<T>&#xff0c;其中HashSet<T>包含不重复元素的无序列表&#xff0c;SortedSet<T>包含不重复元素的有序列…

数据科学必备Python编程基础

前言 对于Python复杂的编程语言中提取了数据分析常用的数据处理以及数据可视化等数据分析师常用的内容&#xff0c;区别与其他的Python编程教程&#xff0c;如果是纯开发的小伙伴&#xff0c;看完本系列的文章仅仅只能掌握数据相关处理的内容&#xff0c;并不能完全掌握开发方…

RestoreDet

来说说低分辨率图像中目标检测吧~~ 超分辨率&#xff08;SR&#xff09;等图像恢复算法是退化图像中目标检测不可或缺的预处理模块。然而&#xff0c;这些算法中的大多数假设退化是固定的并且是先验已知的。 论文地址&#xff1a;https://arxiv.org/pdf/2201.02314.pdf 当真…

四、文件管理(三)文件系统

目录 3.1文件系统结构 3.2文件系统布局 3.2.1文件系统在外存中的结构 3.2.2文件系统在内存中的结构 3.3外存空闲空间管理 3.3.1空闲表法 3.3.2空闲链表法 3.3.3位示图法 3.3.4成组链接法 3.4虚拟文件系统 3.5文件系统挂载(mounting) 3.1文件系统结构 从不同的角度出…

柚子是肝病“催化剂”吗?医生:滋养肝细胞,5种水果或可常吃

人体就像是一台大型的机器&#xff0c;五脏六腑就像是机器里的重要组成部分&#xff0c;血管是为五脏六腑输送机油的管道&#xff0c;骨骼是机器的整体框架等&#xff0c;它们彼此之间互相配合&#xff0c;机器才能够正常运转。 如果其中一个构造受损了&#xff0c;那么会影响到…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java散酒营销系统w5at6

对于计算机专业的学生最头疼的就是临近毕业时的毕业设计,对于如何选题,技术选型等这些问题,难道了大部分人,确实,还没毕业的学生对于这些问题还比较陌生,只有学习的理论知识,没有实战经验怎么能独自完成毕业设计这一系列的流程,今天我们就聊聊如何快速应对这一难题. 比较容易的…

第二证券|元宇宙赛道西北首个“吃螃蟹者”入场

元世界展开势头一浪高过一浪之际&#xff0c;地处西北的咸阳高新区也下决心参加这场比赛。 近来&#xff0c;咸阳高新区管委会发布《咸阳高新区元世界工业先行区举动方案》&#xff0c;对行将打出的元世界“先手牌”从多个维度予以规划。 值得关注的是&#xff0c;外界印象中&…

iOS视频流采集概述(AVCaptureSession)

需求&#xff1a;需要采集到视频帧数据从而可以进行一系列处理(如: 裁剪&#xff0c;旋转&#xff0c;美颜&#xff0c;特效....). 所以,必须采集到视频帧数据. 阅读前提: 使用AVFoundation框架 采集音视频帧数据 Overview AVCaptureSession:使用相机或麦克风实时采集音视频…

Java编程实战12:解数独

目录解数独题目示例 1提示解答解题思路完整代码解数独 题目 编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能…