Qt使用I.MX6U开发板上的按键(原理:将电脑键盘方向键↓在Qt中的枚举值与开发板中按键定义的枚举值一致,这样电脑端测试效果就与开发板的一致)

在上篇介绍了Qt点亮I.MX6U开发板的一个LED,对于Qt控制I.MX6U开发板的一个蜂鸣器原理也是一样的,就不做详细介绍,具体可参考Qt控制I.MX6U开发板的一个蜂鸣器,本篇介绍Qt使用I.MX6U开发板上的按键的相关内容。

1. 开发板硬件图及板卡按键在电脑键盘中的对应原理

打开“【正点原子】I.MX6U嵌入式Qt开发指南V1.0.21”,该文件最前面就是开发板的硬件图。
在这里插入图片描述
在这里插入图片描述
上面第一个图中的时阿尔法的板子,下为6U的MINI版,6U的IO比较紧张,所以就只留了一个IO给上图中的黄色按键使用。

Qt开发是如何识别6U的key0按键并在电脑上进行程序开发呢?

我们知道Qt可以识别键盘输入,键盘即是按键,那是否可以将开发板上的按键当做键盘上的按键呢?
这样当然也是可以的,Qt可以识别键盘上的输入,键盘上的数值早在系统的底层编好码了,系统就可以识别这种编码。同理,将开发板上的按键进行编码,系统也就可以识别这种编码。只要两者对应起来就可以实现电脑测试效果与开发板测试效果一致。

本篇将会介绍在开发板中已经配置了"#define KEY_VOLUMEDOWN 114"的情况下,同样使用电脑键盘在Qt中定义的“KEY_VOLUMEDOWN”枚举进行代替(对应了键盘方向键↓)仿真,后将通用的代码拷贝到开发板中进行测试。

2. 出厂内核设备树中注册的按键

l.MX6U设备树路径为:arch/arm/boot/dts/imx6ull-14x14-evk.dts
STM32MP157设备树路径为:arch/arm/boot/dts/stm32mp157datk.dts

对开发板上的按键进行编码,系统就可以识别编码。下面应该就是l.MX6U板卡Linux源码的关于按键部分的内容-按键的驱动
在这里插入图片描述
对开发板上的按键进行编码,键值设置为114也就是完成了编码。114是对应键盘中的哪个值呢?

3. 如何看这个按键的键值对应键盘中的按键

键值宏定义是在<linux/input.h>头文件中

下图在Linux中按键的键值在键盘中是无法找到的,此处配置的是比较特殊的:“#define KEY_VOLUMEDOWN 114”,KEY_VOLUMEDOWN也就是音量的加减键,老的电脑键盘上可能可以找到,现在的键盘都是用上下键来实现音量的加减等功能,但是现在手机上还是有音量的加减键的(这是因为手机的系统是安卓,安卓的底层也是linux)。
在这里插入图片描述
想要监测这个 KEY0,首先正点原子的出厂内核已经默认将这个按键注册成了 gpio-keys 类型设备,键值为 114 也就是对应 Qt 的 Key_VolumeDown 键值。 也就是说我们可以直接当这个按键是我们普通键盘的音量减键使用(注意键值为 114 的按键比较特殊,并不能直接在我们普通的键盘上找到,有些笔记本电脑使用 FN + F6 等组合直接代替了音量减键)。

4. 程序开发

4.1 项目简介

我们在本例中使用 Key_Down(键盘方向键↓)在Windows/Ubuntu 上测试,在开发板上还是使用 KEY0 按键测试。

在开发板监测这个 KEY0 有很多方法。 比如使用 C 语言开一个线程监测这个按键,或者按本例重写键盘事件来监测 KEY0 按键按下或者松开。

项目简介: 监测 KEY0 按键的按下和松开。 使用一个标签文本, 通过按键按下来改变标签文本的文字属性。

4.2 mainwindow.h

1 #ifndef MAINWINDOW_H
2 #define MAINWINDOW_H
3 4
#include <QMainWindow>
5 #include <QKeyEvent>
6 #include <QLabel>
7 #include <QDebug>
8 #include <QEvent>
9
10 class MainWindow : public QMainWindow
11 {
12 Q_OBJECT
13
14 public:
15 MainWindow(QWidget *parent = nullptr);
16 ~MainWindow();
17
18 private:
19 /* 标签文本 */
20 QLabel *label;
21
22 /* 重写按键事件 */
23 void keyPressEvent(QKeyEvent *event);
24 void keyReleaseEvent(QKeyEvent *event);
25 };
26
27 #endif // MAINWINDOW_H

第 23~24 行,声明需要重写的按键事件类型。分别是按下事件和松开事件。通过重写这两个事件可以监测到键盘或 KEY0 按下的状态。

4.3 mainwindow.cpp

#include "mainwindow.h"
2 #include <QGuiApplication>
3 #include <QScreen>
4 #include <QRect>
5 6
MainWindow::MainWindow(QWidget *parent)
7 : QMainWindow(parent)
8 {
9 /* 获取屏幕的分辨率, Qt 官方建议使用这
10 * 种方法获取屏幕分辨率,防上多屏设备导致对应不上
11 * 注意,这是获取整个桌面系统的分辨率
12 */
13 QList <QScreen *> list_screen = QGuiApplication::screens();
14
15 /* 如果是 ARM 平台,直接设置大小为屏幕的大小 */
16 #if __arm__
17 /* 重设大小 */
18 this->resize(list_screen.at(0)->geometry().width(),
19 list_screen.at(0)->geometry().height());
20 #else
21 /* 否则则设置主窗体大小为 800x480 */
22 this->setGeometry(0, 0, 800, 480);
23 #endif
24
25 /* 标签实例化 */
26 label = new QLabel(this);
27
28 /* 设置默认文本 */
29 #if __arm__
30 label->setText("VolumeDown 松开状态");
31 #else
32 label->setText("Down 按键松开");
33 #endif
34
35 /* 设置对齐方式 */
36 label->setAlignment(Qt::AlignCenter);
37
38 /* 居中显示 */
39 setCentralWidget(label);
40 }
41
42 MainWindow::~MainWindow()
43 {
44 }
45
46 void MainWindow::keyPressEvent(QKeyEvent *event)
47 {
48 #if __arm__
49 /* 判断按下的按键,也就是板子 KEY0 按键 */
50 if(event->key() == Qt::Key_VolumeDown) {
51 /* 设置 label 的文本 */
52 label->setText("VolumeDown 按键按下");
53 }
54 #else
55 /* 判断按下的按键,也就是"↓"方向键 */
56 if(event->key() == Qt::Key_Down) {
57 /* 设置 label 的文本 */
58 label->setText("Down 按键按下");
59 }
60
61 #endif
62 /* 保存默认事件 */
63 QWidget::keyPressEvent(event);
64 }
65
66 void MainWindow::keyReleaseEvent(QKeyEvent *event)
67 {
68 #if __arm__
69 /* 判断松开的按键,也就是板子 KEY0 按键 */
70 if(event->key() == Qt::Key_VolumeDown) {
71 /* 设置 label 的文本 */
72 label->setText("VolumeDown 按键松开");
73 }
74 #else
75 /* 判断按下的按键,也就是"↓"方向键 */
76 if(event->key() == Qt::Key_Down) {
77 /* 设置 label 的文本 */
78 label->setText("Down 按键松开");
79 }
80 #endif
81 /* 保存默认事件 */
82 QWidget::keyReleaseEvent(event);
83 }

第 9 行~23 行,界面初始化设置,在嵌入式里,根据实际的屏的大小,设置全屏显示。按钮居中显示。
第 46~83 行, 重写按下事件和松开事件,通过判断event->key()等哪个按键,就可以知道是哪个按键按下或者松开了。 并设置了标签文本的属性。

4.4 程序运行效果

Ubuntu/Windows 上当焦点聚集到此应用程序窗口时,按下方向键“↓”,标签文本的值会改变为“Down 按键按下”,当松开方向键“↓”,标签的文本值会改变为默认状态“Down 按键松开”。
同理在开发板上,按下 KEY0 键则会打印“VolumeDown 按键按下”,松开 KEY0 键会打印“VolumeDown 按键松开”。
在这里插入图片描述
实际测试时代码不同,只是使用对应的枚举来改变界面效果,实际运行效果如下:按钮按下后界面改变,并会提示按键按下
在这里插入图片描述

对应地址:Qt使用I.MX6U开发板上的按键

要实现Qt开发板的网络通信,可以考虑使用Socket编程,通过TCP或UDP协议进行数据传输。 具体实现步骤如下: 1. 在开发板上创建一个Socket服务器程序,等待Qt客户连接。 2. 在Qt客户,创建一个Socket客户程序,通过IP地址和口号连接到开发板上的Socket服务器。 3. Qt客户通过Socket向开发板发送控制指令,例如控制开发板外围设备。 4. 在开发板上,接收Qt客户发送的指令,并执行相应的操作。 下面是一个简单的示例代码,演示如何在Qt实现按钮控制开发板外围设备: ```c++ // Qt客户代码 #include <QtWidgets> #include <QTcpSocket> class Client : public QWidget { Q_OBJECT public: Client(QWidget *parent = nullptr) : QWidget(parent) { m_socket = new QTcpSocket(this); connect(m_socket, &QTcpSocket::connected, this, &Client::onConnected); connect(m_socket, &QTcpSocket::readyRead, this, &Client::onReadyRead); m_ipEdit = new QLineEdit("192.168.1.100"); m_portEdit = new QLineEdit("1234"); m_connectBtn = new QPushButton("Connect"); connect(m_connectBtn, &QPushButton::clicked, this, &Client::onConnectClicked); m_deviceBtn = new QPushButton("Device On"); connect(m_deviceBtn, &QPushButton::clicked, this, &Client::onDeviceClicked); QGridLayout *layout = new QGridLayout; layout->addWidget(new QLabel("IP Address:"), 0, 0); layout->addWidget(m_ipEdit, 0, 1); layout->addWidget(new QLabel("Port:"), 1, 0); layout->addWidget(m_portEdit, 1, 1); layout->addWidget(m_connectBtn, 2, 0, 1, 2); layout->addWidget(m_deviceBtn, 3, 0, 1, 2); setLayout(layout); } private slots: void onConnectClicked() { QString ip = m_ipEdit->text(); int port = m_portEdit->text().toInt(); m_socket->connectToHost(ip, port); } void onDeviceClicked() { if (m_socket->state() == QAbstractSocket::ConnectedState) { m_socket->write("Device On"); } } void onConnected() { qDebug() << "Connected to server."; } void onReadyRead() { QByteArray data = m_socket->readAll(); qDebug() << "Received data:" << data; } private: QLineEdit *m_ipEdit; QLineEdit *m_portEdit; QPushButton *m_connectBtn; QPushButton *m_deviceBtn; QTcpSocket *m_socket; }; // 开发板服务器代码 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <unistd.h> int main() { int server_fd, client_fd; struct sockaddr_in server_addr, client_addr; socklen_t client_len = sizeof(client_addr); char buffer[1024]; // 创建Socket服务器 server_fd = socket(AF_INET, SOCK_STREAM, 0); if (server_fd == -1) { perror("socket"); exit(EXIT_FAILURE); } // 绑定IP地址和口号 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr("192.168.1.100"); server_addr.sin_port = htons(1234); if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { perror("bind"); exit(EXIT_FAILURE); } // 监听客户连接 if (listen(server_fd, 5) == -1) { perror("listen"); exit(EXIT_FAILURE); } // 接受客户连接 client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len); if (client_fd == -1) { perror("accept"); exit(EXIT_FAILURE); } // 接收客户发送的指令 while (1) { memset(buffer, 0, sizeof(buffer)); if (read(client_fd, buffer, sizeof(buffer)) == -1) { perror("read"); exit(EXIT_FAILURE); } printf("Received data: %s\n", buffer); // 执行相应的操作 if (strcmp(buffer, "Device On") == 0) { printf("Device On!\n"); } } // 关闭Socket连接 close(client_fd); close(server_fd); return 0; } ``` 在上面的示例代码Qt客户通过Socket连接到开发板上的Socket服务器,然后通过按钮控制开发板外围设备。开发板服务器接收到客户发送的指令后,根据指令执行相应的操作。 需要注意的是,在实际使用,还需要考虑通信协议、数据格式等问题。此外,为了提高系统的安全性,还需要考虑数据加密、身份验证等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十月旧城

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值