「Qt Widget中文示例指南」如何实现一个平板电脑示例?(一)

server/2024/10/15 1:29:40/

Qt 是目前最先进、最完整的跨平台C++开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。

「Qt Widget中文示例指南」如何实现一个平板电脑示例?

当您在平板电脑上使用Qt应用程序时, QTabletEvents就会生成。如果您想处理tablet事件,需要重新实现tabletEvent()事件处理程序。当用于绘图的工具(触控笔)进入并离开写字板附近时(即,当它关闭但未按下时),当工具被按下并从中释放时,当工具在写字板上移动时,以及当工具上的一个按钮被按下或释放时,都会产生事件。

QTabletEvent中可用的信息取决于所使用的设备,本实例可以处理多达三种不同绘图工具的平板电脑:触控笔、喷枪和艺术笔。对于这些事件,将包含工具的位置,平板电脑上的压力、按钮状态、垂直倾斜和水平倾斜(即设备与平板电脑垂直方向之间的角度,如果平板电脑硬件可以提供)。喷枪有指轮,这个位置也可以在平板电脑事件中找到;艺术笔提供围绕垂直于平板表面的轴旋转,因此它可以用于书法。

在这个例子中,我们实现了一个绘图程序。您可以用触控笔在平板电脑上画画,就像在纸上用铅笔一样。当用喷枪画画时,会得到一种虚拟的油漆喷雾,手指轮用来改变喷雾的密度。当您用美术笔绘制时,会得到一条线,它的宽度和端点角度取决于笔的旋转,压力和倾斜也可以被分配来改变颜色的alpha和饱和度值以及笔画的宽度。

本示例包括以下内容:

  • MainWindow类继承QMainWindow,创建菜单,并连接它们的槽和信号。
  • TabletCanvas类继承了QWidget并接收tablet事件,它使用事件将其绘制到屏幕外的像素图上,然后渲染它。
  • TabletApplication类继承了QApplication,这个类处理平板电脑接近事件。
  • main()函数创建一个主窗口,并将其显示为顶层窗口。

点击获取Qt Widget组件下载

MainWindow类定义

MainWindow创建一个TabletCanvas,并将其设置为中心小部件。

class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
MainWindow(TabletCanvas *canvas);private slots:
void setBrushColor();
void setAlphaValuator(QAction *action);
void setLineWidthValuator(QAction *action);
void setSaturationValuator(QAction *action);
void setEventCompression(bool compress);
bool save();
void load();
void clear();
void about();private:
void createMenus();TabletCanvas *m_canvas;
QColorDialog *m_colorDialog = nullptr;
};

createMenus()用操作设置菜单,我们有一个QActionGroup用于分别改变alpha通道、颜色饱和度和线宽的操作。操作组连接到setAlphaValuator()、setSaturationValuator()和setLineWidthValuator()插槽,它们调用TabletCanvas中的函数。

MainWindow类实现

我们从构造函数MainWindow()开始:

MainWindow::MainWindow(TabletCanvas *canvas)
: m_canvas(canvas)
{
createMenus();
setWindowTitle(tr("Tablet Example"));
setCentralWidget(m_canvas);
QCoreApplication::setAttribute(Qt::AA_CompressHighFrequencyEvents);
}
在构造函数中,我们调用createMenus()来创建所有的操作和菜单,并将画布设置为中心小部件。
MainWindow::MainWindow(TabletCanvas *canvas)
: m_canvas(canvas)
{
createMenus();
setWindowTitle(tr("Tablet Example"));
setCentralWidget(m_canvas);
QCoreApplication::setAttribute(Qt::AA_CompressHighFrequencyEvents);
}

在createMenus()的开头,我们填充了File菜单。使用在Qt 5.6中引入的addAction()的重载来创建带有快捷方式(也可以是图标)的菜单项,将其添加到菜单中,并将其连接到插槽,所有这些都只需要一行代码,使用QKeySequence为这些常用菜单项获取特定于平台的标准快捷键。

我们还填充了画笔菜单,更改笔刷的命令通常没有标准的快捷方式,因此使用tr()来翻译快捷方式以及应用程序的语言翻译。

现在,我们将在Tablet菜单的子菜单中创建一组互斥操作,用于选择每个QTabletEvent QMenu *alphaChannelMenu = tabletMenu->addMenu(tr("&Alpha Channel"));

QAction *alphaChannelPressureAction = alphaChannelMenu->addAction(tr("&Pressure"));
alphaChannelPressureAction->setData(TabletCanvas::PressureValuator);
alphaChannelPressureAction->setCheckable(true);QAction *alphaChannelTangentialPressureAction = alphaChannelMenu->addAction(tr("T&angential Pressure"));
alphaChannelTangentialPressureAction->setData(TabletCanvas::TangentialPressureValuator);
alphaChannelTangentialPressureAction->setCheckable(true);
alphaChannelTangentialPressureAction->setChecked(true);QAction *alphaChannelTiltAction = alphaChannelMenu->addAction(tr("&Tilt"));
alphaChannelTiltAction->setData(TabletCanvas::TiltValuator);
alphaChannelTiltAction->setCheckable(true);QAction *noAlphaChannelAction = alphaChannelMenu->addAction(tr("No Alpha Channel"));
noAlphaChannelAction->setData(TabletCanvas::NoValuator);
noAlphaChannelAction->setCheckable(true);QActionGroup *alphaChannelGroup = new QActionGroup(this);
alphaChannelGroup->addAction(alphaChannelPressureAction);
alphaChannelGroup->addAction(alphaChannelTangentialPressureAction);
alphaChannelGroup->addAction(alphaChannelTiltAction);
alphaChannelGroup->addAction(noAlphaChannelAction);
connect(alphaChannelGroup, &QActionGroup::triggered,
this, &MainWindow::setAlphaValuator);

我们希望用户能够选择绘画颜色的alpha分量是否应该通过平板压力、倾斜或喷枪工具上拇指轮的位置来调节。对每个选择都有一个操作,另外一个操作是选择不改变alpha,也就是说,保持颜色不透明。我们让操作可检查,然后alphaChannelGroup将确保在任何时候只检查一个操作。当一个操作被检查时,triggered()信号从组中发出,因此我们将其连接到MainWindow::setAlphaValuator(),它将需要知道从现在开始关注QTabletEvent的哪个属性(估值器),因此使用QAction::data属性来传递此信息。(为了实现这一点,枚举Valuator必须是一个注册元类型,以便它可以插入到QVariant中。这是通过tabletcanvas.h中的Q_ENUM声明完成的。)

下面是setAlphaValuator()的实现:

void MainWindow::setAlphaValuator(QAction *action)
{
m_canvas->setAlphaChannelValuator(qvariant_cast<TabletCanvas::Valuator>(action->data()));
}

它只需要从QAction::data()中检索Valuator枚举,并将其传递给tablecanvas::setAlphaChannelValuator()。如果不使用data属性,则需要比较QAction指针本身,例如在switch语句中。但这需要在类变量中保留指向每个QAction的指针,以便进行比较。

下面是setBrushColor()的实现:

void MainWindow::setBrushColor()
{
if (!m_colorDialog) {
m_colorDialog = new QColorDialog(this);
m_colorDialog->setModal(false);
m_colorDialog->setCurrentColor(m_canvas->color());
connect(m_colorDialog, &QColorDialog::colorSelected, m_canvas, &TabletCanvas::setColor);
}
m_colorDialog->setVisible(true);
}

我们在用户第一次选择画笔颜色时延迟初始化QColorDialog,从菜单或通过操作快捷方式。当对话框打开时,每次用户选择不同的颜色时,TabletCanvas::setColor()将被调用来更改绘图颜色。因为它是一个非模态对话框,所以用户可以自由地让颜色对话框保持打开状态,以便能够方便而频繁地更改颜色,或者关闭它并稍后重新打开它。

下面是save()的实现:

bool MainWindow::save()
{
QString path = QDir::currentPath() + "/untitled.png";
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Picture"),
path);
bool success = m_canvas->saveImage(fileName);
if (!success)
QMessageBox::information(this, "Error Saving Picture",
"Could not save the image");
return success;
}

我们使用QFileDialog让用户选择一个文件来保存绘图,然后调用TabletCanvas::saveImage()将其实际写入文件。

下面是load()的实现:

void MainWindow::load()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Open Picture"),
QDir::currentPath());if (!m_canvas->loadImage(fileName))
QMessageBox::information(this, "Error Opening Picture",
"Could not open picture");
}

我们让用户选择要用QFileDialog打开的图像文件,然后要求画布使用loadImage()加载图像。

下面是about()的实现:

void MainWindow::about()
{
QMessageBox::about(this, tr("About Tablet Example"),
tr("This example shows how to use a graphics drawing tablet in Qt."));
}

我们将显示一个消息框,其中包含对示例的简短描述。

Qt Widget组件推荐
  • QtitanRibbon - Ribbon UI组件:是一款遵循Microsoft Ribbon UI Paradigm for Qt技术的Ribbon UI组件,QtitanRibbon致力于为Windows、Linux和Mac OS X提供功能完整的Ribbon组件。
  • QtitanChart - Qt类图表组件:是一个C ++库,代表一组控件,这些控件使您可以快速地为应用程序提供漂亮而丰富的图表。
  • QtitanDataGrid - Qt网格组件:提供了一套完整的标准 QTableView 函数和传统组件无法实现的独特功能。使您能够将不同来源的各类数据加载到一个快速、灵活且功能强大的可编辑网格中,支持排序、分组、报告、创建带状列、拖放按钮和许多其他方便的功能。
  • QtitanDocking:允许您像 Visual Studio 一样为您的伟大应用程序配备可停靠面板和可停靠工具栏。黑色、白色、蓝色调色板完全支持 Visual Studio 2019 主题!

http://www.ppmy.cn/server/124861.html

相关文章

Linux-TCP重传

问题描述&#xff1a; 应用系统进行切换&#xff0c;包含业务流量切换&#xff08;即TongWeb主备切换&#xff09;和MYSQL数据库主备切换。首先进行流量切换&#xff0c;然后进行数据库主备切换。切换后发现备机TongWeb上有两批次慢请求&#xff0c;第一批慢请求响应时间在133…

9.26-9.29学习

一.项目结构的建立 5个微服务模块 新建好各个模块后&#xff0c;在项目pom下引入各模块。各pom文件指定springboot版本2.1.8.RELEASE .gitignore #表示任意路径下的xx文件 **/mvnw **/mvnw.cmd**/.mvn **/target/.idea**/.gitignore 二.数据库初始化 一个微服务模块对应一个数…

Hi3536AV100 22AP20/SS626V100 芯片及开发板

22AP20 是针对多路高清/超高清&#xff08;1080p/4M/5M/4K&#xff09;智能 NVR 产品应用开发的新一代专业高端 SoC 芯 片。22AP20 集成了 ARM Cortex-A55 八核处理器和性能强大的图像分析工具处理器&#xff0c;支持多种智能算法 应用。22AP20 支持 24 路 1080p 多协议解码及 …

2024年配置YOLOX运行环境+windows+pycharm24.0.1+GPU

1.配置时间2024/9/25 2.Anaconda-python版本3.7&#xff0c;yolox版本0.2.0 YOLOX网址: https://github.com/Megvii-BaseDetection/YOLOX 本人下载的这个版本 1.创建虚拟环境 conda create -n yolox37 python37 激活 conda activate yolox37 2.安装Pytorch cuda等&…

正向代理与反向代理:原理、区别以及应用(Nginx 和 Tomcat)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言1. 实现原理正向代理工作流程&#xff1a; 反向代理工作流程&#xff1a; 区别 2. 使用案例Nginx作为正向代理Nginx作为反向代理Tomcat作为反向代理 3. 适用场景…

8月面试总结

面试总结 前言一、公司甲&#xff08;一&#xff09;技术面&#xff08;二&#xff09;HR面 二、公司乙三、公司丙&#xff08;一&#xff09;技术面HR面 四、公司丁五、公司戊六、公司己七、公司庚八、公司辛九、公司壬总结 前言 提示&#xff1a;这里可以添加本文要记录的大…

网络安全:保护您的数字世界

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

excel导出图片---HSSFWorkbook--SXSSFWorkbook

1 概述 平时在工作中&#xff0c;excel导出图片经常会用到&#xff0c;但奈何HSSFWorkbook导出数据数量有限制问题&#xff0c;所以企业里大多都用SXSSFWorkbook格式&#xff0c;很少用HSSFWorkbook。所以今天以这两种格式分别记录下&#xff0c;图片的导出过程。 2 HSSFWork…