如何在QT中读取串口数据

如何在QT中读取串口数据,第1张

一、文件下载

文件下载地址:

也可以下载我上传到网盘上的:

二、文件内容介绍

1下载到的文件为qextserialport-12win-alpha ,解压并打开后其内容如下。

(点击可以查看清晰大图)

下面分别介绍:

(1)doc文件夹中的文件内容是QextSerialPort类和QextBaseType的简单的说明,我们可以使用记事本程序将它们打开。

(2)examples文件夹中是几个例子程序,可以看一下它的源码,不过想运行它们好像会出很多问题啊。

(3)html文件夹中是QextSerialPort类的使用文档。

(4)然后就是剩下的几个文件了。其中qextserialenumeratorcpp及qextserialenumeratorh文件中定

义的QextSerialEnumerator类是用来获取平台上可用的串口信息的。不过,这个类好像并不怎么好用,而且它不是我们关注的重点,所以下面

就不再介绍它了。

(5)qextserialbasecpp和qextserialbaseh文件定义了一个QextSerialBase

类,win_qextserialportcpp和win_qextserialporth文件定义了一个Win_QextSerialPort

类,posix_qextserialportcpp和posix_qextserialporth文件定义了一个

Posix_QextSerialPort类,qextserialportcpp和qextserialporth文件定义了一个

QextSerialPort类。这个QextSerialPort类就是我们上面所说的那个,它是所有这些类的子类,是最高的抽象,它屏蔽了平台特征,

使得在任何平台上都可以使用它。

2几个类的简单介绍。

下面是这几个类的关系图。

可以看到它们都继承自QIODevice类,所以该类的一些函数我们也可以直接来使用。图中还有一个QextBaseType类,其实它只是一个标

识,没有具体的内容,它用来表示Win_QextSerialPort或Posix_QextSerialPort

中的一个类,因为在QextSerialPort类中使用了条件编译,所以QextSerialPort类既可以继承自

Win_QextSerialPort类,也可以继承自Posix_QextSerialPort类,所以使用了QextBaseType来表示。这一点

我们可以在qextserialporth文件中看到。再说QextSerialPort类,其实它只是为了方便程序的跨平台编译,使用它可以在不同的

平台上,根据不同的条件编译继承不同的类。所以它只是一个抽象,提供了几个构造函数而已,并没有具体的内容。在qextserialporth文件中的

条件编译内容如下:

#ifdef_TTY_POSIX_

#include“posix_qextserialporth”

#define QextBaseTypePosix_QextSerialPort

#else

#include“win_qextserialporth”

#define QextBaseTypeWin_QextSerialPort

#endif

所以,其实我们没有必要使用这个类,直接使用Win_QextSerialPort或Posix_QextSerialPort就可以了。当然如果

你想使用这个类,实现同样的源程序可以直接在Windows和Linux下编译运行,那么一定要注意在Linux下这里需要添加

#define _TTY_POSIX_ 。而我们这里为了使得程序更明了,所以没有使用该类,下面也就不再介绍它了。

QextSerialBase类继承自QIODevice类,它提供了 *** 作串口所必需的一些变量和函数等,而

Win_QextSerialPort和Posix_QextSerialPort均继承自QextSerialBase

类,Win_QextSerialPort类添加了Windows平台下 *** 作串口的一些功能,Posix_QextSerialPort类添加了

Linux平台下 *** 作串口的一些功能。所以说,在Windows下我们使用Win_QextSerialPort类,在Linux下我们使用

Posix_QextSerialPort类。

3在QextSerialBase类中还涉及到了一个枚举变量QueryMode。

它有两个值Polling和EventDriven

。QueryMode指的是读取串口的方式,下面我们称为查询模式,我们将Polling称为查询方式Polling,将EventDriven称为事件驱动方式。

事件驱动方式EventDriven就是使用事件处理串口的读取,一旦有数据到来,就会发出readyRead()信号,我们可以关联该信号来读取串口的数据。在事件驱动的方式下,串口的读写是异步的,调用读写函数会立即返回,它们不会冻结调用线程。

而查询方式Polling则不同,读写函数是同步执行的,信号不能工作在这种模式下,而且有些功能也无法实现。但是这种模式下的开销较小。我们需要自己建立定时器来读取串口的数据。

在Windows下支持以上两种模式,而在Linux下只支持Polling模式。

三、小结。

这里讲了这么多,最后要说的只是,我们在Qt中使用这个类编写串口程序,根据平台的不同只需要分别使用四个文件。

在Windows下是:

qextserialbasecpp和qextserialbaseh

以及win_qextserialportcpp和win_qextserialporth

在Linux下是:

qextserialbasecpp和qextserialbaseh

以及posix_qextserialportcpp和posix_qextserialporth

而在Windows下我们可以使用事件驱动EventDriven方式,也可以使用查询Polling方式,但是在Linux下我们只能使用查询Polling方式。

第二部分 在Windows下编写串口通信程序

我们的环境是Windowsxp,Qt463及Qt Creator20。

第一,下面我们首先使用事件驱动来实现串口通信。

1新建工程。

我们在QtCreator中新建Qt Gui工程,命名为myCom,Base Class选择QWidget。

2添加文件。

我们将那四个文件添加到工程文件夹中。如下图。

然后我们将这四个文件添加到工程中,在Qt

Creator的工程列表中的工程文件夹上点击鼠标右键,在d出的菜单中选择“AddExisting Files”菜单。如下图。

我们在d出的对话框中选中四个文件,按下“打开”按钮即可,如下图。

最终工程文件列表如下图。

3更改界面。

我们将界面设计如下。

其中的TextBrowser 部件用来显示接收到的数据,Line Edit部件用来输入要发送的数据,Push

Button按钮用来发送数据。我们保持各部件的属性为默认值即可。

4 我们在widgeth文件中进行对象及函数声明。

添加头文件包含:#include“win_qextserialporth”

然后在private中声明对象:Win_QextSerialPort myCom;

声明私有槽函数:

private slots:

voidon_pushButton_clicked(); //”发送数据”按钮槽函数

void readMyCom(); //读取串口

5在widgetcpp文件中进行更改。

在构造函数中添加代码,完成后,构造函数内容如下:

Widget::Widget(QWidgetparent) :

QWidget(parent),

ui(newUi::Widget)

{

ui->setupUi(this);

myCom=

new Win_QextSerialPort(“COM1″,QextSerialBase::EventDriven);

//定义串口对象,指定串口名和查询模式,这里使用事件驱动EventDriven

myCom->open(QIODevice::ReadWrite);

//以读写方式打开串口

myCom->setBaudRate(BAUD9600);

//波特率设置,我们设置为9600

myCom->setDataBits(DATA_8);

//数据位设置,我们设置为8位数据位

myCom->setParity(PAR_NONE);

//奇偶校验设置,我们设置为无校验

myCom->setStopBits(STOP_1);

//停止位设置,我们设置为1位停止位

myCom->setFlowControl(FLOW_OFF);

//数据流控制设置,我们设置为无数据流控制

myCom->setTimeout(500);

//延时设置,我们设置为延时500ms,这个在Windows下好像不起作用

connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));

//信号和槽函数关联,当串口缓冲区有数据时,进行读串口 *** 作

}

实现槽函数:

void Widget::readMyCom()//读取串口数据并显示出来

{

QByteArray

temp = myCom->readAll();

//读取串口缓冲区的所有数据给临时变量temp

ui->textBrowser->insertPlainText(temp);

//将串口的数据显示在窗口的文本浏览器中

}

voidWidget::on_pushButton_clicked() //发送数据

{

myCom->write(ui->lineEdit->text()toAscii());

//以ASCII码形式将数据写入串口

}

6此时,我们运行程序,效果如下。

可以看到,已经成功完成通信了。

(注:我们这里下位机使用的是单片机,它使用串口与计算机的COM1相连。单片机上运行的程序的功能是,接收到一个字符便向上位机发送一个字符串然后发送接收到的字符。)

两个重要问题的讲解:

一、关于数据接收。

我们想在程序中对接收的数据进行控制,但是readyRead()信号是一旦有数据到来就发射的,不过我们可以使用bytesAvailable()函数来检查已经获得的字节数,从而对数据接收进行控制。

(1)我们在widgetcpp中添加头文件包含:#include

然后在读串口函数中添加一行代码,如下:

void Widget::readMyCom() //读取串口数据并显示出来

{

qDebug()

<< “read:

“<<myCom->bytesAvailable()<<”bytes”;

//我们输出每次获得的字节数

QByteArray

temp = myCom->readAll();

ui->textBrowser->insertPlainText(temp);

}

运行程序,效果如下:

可以看到,我们获取的数据并不是一次获得的。

(2)利用上面的结论,我们可以让串口缓冲区拥有了一定的数据后再读取。

void Widget::readMyCom()

{

if(myCom->bytesAvailable()>=8 )

//如果可用数据大于或等于8字节再读取

{

qDebug()

<< “read:

“<<myCom->bytesAvailable()<<”bytes”;

QByteArray

temp = myCom->readAll();

ui->textBrowser->insertPlainText(temp);

}

}

运行程序,效果如下:

我们发送了两次数据,可以看到,这样实现了每8个字节读取一次,而最后剩余的不够8个字节的数据将会和后面的数据一起读出。

然后我们将8改为3,发送一次数据,效果如下:

改为7,发送两次数据,效果如下:

改为11,发送两次数据,效果如下:

改为17,发送三次数据,效果如下:

重要结论:我们发送一次数据,应该获得37字节的数据,然后我们对比上面的结果,发现了什么?是的,其实串口每次读取8字节的数据放到缓冲区,只有

数据总数小于8字节时,才会读取小于8字节的数据。为了再次验证我们的结论,我们可以将上面程序中的“>=”改为“==”,那么只有8的倍数才能读

取数据(当然这里37也可以),你可以测试一下。

关于接收数据方面,可以根据你自己的需要再去进行研究和改进,这里只是抛砖引玉。

二、关于发送数据。

我们也可以使用函数获取要发送的数据的大小,这里有个bytesToWrite()可以获取要发送的字节数。例如将发送数据更改如下:

voidWidget::on_pushButton_clicked() //发送数据

{

myCom->write(ui->lineEdit->text()toAscii());

qDebug()

<< “write:

“<<myCom->bytesToWrite()<<”bytes”;

//输出要发送的字节数

}

运行后效果如下:

当然,对于要发送的数据的大小我们不是很关心,而且它还有很多方法可以实现,这个还有个bytesWritten()信号函数来获取已经发送的数据的大小,不过好像它不是很好用。这里将它们提出来,只是供大家参考而已。

第二,使用查询方式Polling来实现串口通信。

这里再次说明,Polling方式是不能使用readyRead()信号的,所以我们需要自己设置定时器,来不断地读取缓冲区的数据。

1我们在widgeth中声明一个定时器对象。

添加头文件包含:#include

添加private变量:QTimer readTimer;

2我们在widgetcpp文件中的构造函数中更改。

(1)将串口定义更改为:

myCom =

newWin_QextSerialPort(“COM1″,QextSerialBase::Polling);

//定义串口对象,指定串口名和查询模式,这里使用Polling

(2)定义定时器,并将以前的关联更改为定时器的关联。

readTimer = newQTimer(this);

readTimer->start(100);

//设置延时为100ms

connect(readTimer,SIGNAL(timeout()),this,SLOT(readMyCom()));

//信号和槽函数关联,延时一段时间,进行读串口 *** 作

3此时运行程序,便可以正常收发数据了。

重点:关于延时问题。

上面的程序中可以进行数据的接收了,但是好像中间的延时有点长,要等一会儿才能收到数据,而且即便我们将定时器改为10ms

也不行。问题在哪里呢?其实真正控制串口读写时间的不是我们的定时器,而是延时timeout。我们在构造函数中设置了延时:

myCom->setTimeout(500);

//延时设置,我们设置为延时500ms

我们前面说延时并不起作用,那是因为是在事件驱动的情况下,一旦有数据到来就会触发readyRead()信号,所以延时不起作用。但是现在,真正

控制串口读写数据间隔的就是这个函数。这里值得注意,我们现在所说的串口读写是指底层的串口读写,从上面的程序中我们也可以看到,我们每隔100ms去读

串口,确切地说,应该是去读串口缓冲区。而timeout才是正真的读取串口数据,将读到的数据放入串口缓冲区。所以如果timeout时间很长,即便我

们的定时器时间再短,也是读不到数据的。所以我们这里需要将timeout设置为较小的值,比如10。我们更改代码:

myCom->setTimeout(10);

这样再运行程序,我们就可以很快地获得数据了。

关于数据接收:事件驱动那里的结论依然有用,不过这里更多的是靠读取的时间间隔来控制。

关于发送数据:这时bytesToWrite()函数就不再那么好用了。

第三部分 在Linux下编写串口通信程序

我这里的环境是Ubuntu1004,Qt 463和Qt Creator20

。上面已经提到,在Linux下只能使用Polling的方式读取串口数据,所以我们将上面Windows下的应用Polling的程序在Linux下重

新编译。我们使用Qt Creator打开该工程,然后进行下面的 *** 作。

1文件替换。

将工程中的win_qextserialportcpp和win_qextserialporth文件替换成posix_qextserialportcpp和posix_qextserialporth文件。

(1)我们先删除工程中的win_qextserialportcpp和win_qextserialporth文件。

在工程列表中用鼠标右击win_qextserialporth,然后选择“Remove File”选项。如下图。

在d出的对话框中我们选中“Deletefile permanently”选项,确保删除了工程文件夹中的文件。如下图。

然后我们使用同样的方法删除win_qextserialportcpp文件。

(2)我们按照Windows下添加文件的方法,向工程中添加posix_qextserialportcpp和posix_qextserialporth文件。最终工程文件列表如下。

2设置编码。

(这是因为两个系统使用的默认编码不同造成的,如果你那里没有该问题,可以跳过这一步)

现在我们打开widgetcpp文件,发现中文出现乱码,而且无法编辑。在编辑器最上面有一个**提示条和一个“Select

Encoding”按钮,我们点击该按钮。如下图。

在d出的对话框中我们选择“GB2312”。按下“Reload with Encoding”按钮,中文就可以正常显示了。

3更改程序。

在widgeth文件中:

将以前的#include“win_qextserialporth”更改为#include“posix_qextserialporth”

将以前的Win_QextSerialPortmyCom;更改为Posix_QextSerialPortmyCom;

在widgetcpp文件中:

将以前的myCom= new

Win_QextSerialPort(“COM1″,QextSerialBase::Polling);

更改为:myCom= new

Posix_QextSerialPort(“/dev/ttyS0″,QextSerialBase::Polling);

(这里一定要注意串口名称的写法。)

4下面我们运行程序。

这时可能会出现以下提示。

错误是说一个函数的调用出现了问题。我们点击该错误,定位到出错的位置,然后将那个函数中的第一个参数删除即可。如下图。

5再次运行程序,这时已经可以正常运行了。

6小结

可以看到将Windows下的串口程序在Linux下重新编译是很简单的,我们只需要替换那两个文件,然后更改一下头文件包含,对象定义和串口名即可。

1、关联Qt库。如果是分别安装的Qt Creator和Qt库,而不是安装集成Qt Creator和Qt库的SDK,则需要手动关联Qt库。打开工具→选项菜单,然后选择“构建和运行”一项,再进入Qt版本选项卡。点击右上角的“添加”按钮,然后会让选择qmakeexe文件,我们在Qt(不是Qt Creator)安装目录的bin目录中找到该文件并打开。现在已经默认生成了版本信息,我们点击确定按钮即可。

2、关联MinGW。在安装Qt 486及以后的Qt 4版本时,应该按照安装时的提示来下载相应版本的MinGW,不然编译程序无法运行。如果是Qt4版本,需要使用GCC 44,也就是MinGW需要是44版本的,其他新的版本均不可用。在Qt 48版本,需要下载并指定GDB才能正常调试。下载完MinGW和GDB以后,将其解压到Qt的安装目录中,比如这里都解压到了C:\Qt目录中。打开工具→选项菜单,然后选择“构建和运行”一项,再进入工具链选项卡。点击右上角的“添加”按钮,然后会让选择mingw32-g++exe文件,我们在MinGW安装目录的bin目录中找到该文件并打开。关联GDB则进入调试器选项卡添加GDB相关exe文件。

如果安装的是集成开发包QtSDK,则不需要手动关联Qt库、MinGW和GDB,由Qt自动关联。

注意:Qt5以后版本默认也包含了所有需要的工具,不存在这里的情况,直接下载安装即可使用!

3、在创建桌面版项目时,最好选中“使用影子构建”,这样编译生成的文件会和源码分别存放,如下图所示。编译完成后会发现多了一个helloworld-build-desktop-Qt_4_8_1__4_8_1____目录,里面存放的就是编译生成的文件。这就是前面创建项目讲到的 “使用影子构建” ,如果没有选中这个,那么生成的文件就会和源码在同一个目录里。

4、补充:如果要给生成的exe可执行文件更换一个自定义图标,可以这样做:

(1)在项目中添加一个myapprc(名字可以随意)文件,然后在里面输入下面一行代码:IDI_ICON1               ICON    DISCARDABLE     "appicoico",这里的appicoico就是自己的ico图标文件;

(2)在pro项目文件中添加下面一行代码:RC_FILE = myapprc,

(3)重新编译

如果需要更换新的图标,建议先清理项目的编译文件,再重新编译,否则可能会报错,如下。

“:-1: 错误:No rule to make target `\helloworld\myapprc', needed by `debug/myapp_reso'  Stop”

5、在创建主窗口MainWindow项目后,打开mainwindowui文件进入设计模式。在这里可以看到界面左上角的“在这里输入”,我们可以在这里添加菜单。双击“在这里输入”,将其更改为“文件(&F)”,然后按下回车键,效果如下图所示。这里的&F表明将菜单的快捷键设置为了Alt+ F,可以看到,实际的显示效果中&符号是隐藏的。

同样的方法,我们在文件菜单中添加“新建(&N)”子菜单,效果如下图所示。菜单后面的那个加号图标是用来创建下一级菜单的。

Qt中的一个菜单被看做是一个Action,我们在下面的Action编辑器中可以看到刚才添加的“新建”菜单,如下图所示。

双击该条目,会d出编辑动作对话框,这里可以进行各项设置,比如我们可以设置菜单的快捷键,点击一下快捷键后面的行编辑器,然后按下键盘上的Ctrl + N,这样就可以将该菜单的快捷键设置为Ctrl + N。如下图所示。那么大家可能会问,既然该菜单的快捷键是这么设置的,那么前面设置的“新建(N)”中的N是什么呢?这个可以被称为加速键,就是只有当文件菜单处于激活(显示)状态时,按下N键才会执行新建菜单的功能。

6、Qt中可以使用资源文件将各种类型的文件添加到最终生成的可执行文件中,这样就可以避免使用外部文件可能出现的一些问题。而且,在编译时Qt还会将资源文件进行压缩,我们可能发现生成的可执行文件比我们添加到其中的资源文件还要小。创建完资源文件后会自动打开该资源文件,这里需要先在下面添加前缀,就是点击添加按钮,然后选择前缀,默认的前缀是“/new/prefix1”,这个可以随意修改(不要出现中文字符),我们这里因为要添加,所以修改为/myImages。然后再按下添加按钮来添加文件,这里最好将所有要用到的放到项目目录中。比如我们这里在项目目录中新建了一个images文件夹,然后将需要的图标文件粘贴进去。添加完文件后,如下图所示。

当添加完资源后,一定要按下Ctrl + S来保存资源文件,不然在后面可能无法显示已经添加的资源。

对于添加的资源文件,在项目目录中可以看到,即myResourcesqrc,使用写字板程序将其打开,可以发现它其实就是一个XML文档:

<RCC>

<qresourceprefix="/myImages">

<file>images/filenewpng</file>

<file>images/fileopenpng</file>

<file>images/filesavepng</file>

<file>images/filesaveaspng</file>

<file>images/findpng</file>

</qresource>

</RCC>

7、使用代码添加菜单时,在构造函数中添加如下代码:

QAction openAction = new QAction(QString::fromUtf8("&Open"), this);// 创建新的动作

QIcon icon(":/myImages/images/fileopenpng");// 添加图标

openAction->setIcon(icon);

openAction->setShortcut(QString::fromUtf8("Ctrl+O"));// 设置快捷键

ui->menu_F->addAction(openAction);// 在文件菜单中设置新的打开动作

这里添加图标时,就是使用的资源文件中的图标。使用资源文件,需要在最开始使用冒号,然后添加前缀,后面是文件的路径。在代码中使用文件菜单,就是使用其objectName。大家现在可以运行程序查看效果,当然这里也可以将Open改为中文。

8、向工具栏添加图标:可以将动作编辑器中的动作拖动到工具栏中作为快捷图标使用;可以在工具栏上点击鼠标右键来添加分隔符。

9、使用垂直布局管理器(QVBoxLayout)布局:部件自动垂直排列,并且进行水平拉伸,无论如何改变布局管理器的大小,按钮总是水平方向变化。

使用垂直分裂器(QSplitter)布局:部件自动垂直排列,但进行放大可以发现,使用分裂器按钮纵向是可以变大的,这就是分裂器和布局管理器的重要区别。

10、快速从头文件声明处创建函数定义的方法:到mainwindowh文件中,将鼠标定位到showFindText()函数上,然后点击右键,在d出的菜单中选择“重构”→“在mainwindowcpp添加声明”,或者直接使用Alt+Enter快捷键,这样就会直接在mainwindowcpp文件中添加函数定义,并跳转到该函数处。

11、在QtCreator中有几种快速定位函数的方法:

第一种,在函数声明的地方直接跳转到函数定义的地方。

例如我们在mainwindowh文件的loadFile()函数上点击鼠标右键,在d出的菜单上选择“在方法声明/定义之间切换”,这时就会自动跳转到mainwindowcpp文件中该函数的定义处。如下图所示。当然还可以反向使用。

第二种,快速查看一个文件里的所有函数。

可以在编辑器正上方的下拉框里查看正在编辑的文件中所有的函数的列表,点击一个函数就会跳转到指定位置。如下图所示。

第三种,使用类视图或者大纲视图。

在项目列表上面的下拉框中可以更改查看的内容,如果选择为类视图或者大纲,则会显示文件中所有的函数的列表。如下图所示。

第四种,使用查找功能查看函数的所有调用处。

在一个函数名上点击鼠标右键,然后选择“查找何处被使用”菜单,这时就会在下面的搜索结果栏中显示该函数所有的使用位置。我们可以通过点击一个位置来跳转到该位置。如下图所示。

12、在Action编辑器中,有两个属性toolTip和statusTip,分别为工具栏提示和状态栏提示,如下图

这时运行程序,当光标移动到新建动作上时,在下面的工具栏和状态栏将会出现设置的提示。如下图所示

13、状态信息可以被分为三类:临时信息,如一般的statusTip提示信息,上面讲到的动作提示就是临时信息;正常信息,如显示页数和行号;永久信息,如显示版本号或者日期。可以使用showMessage()函数来显示一个临时消息,它会出现在状态栏的最左边。一般用statusBar->addWidget()函数添加一个QLabel到状态栏上用于显示正常信息,它会生成到状态栏的最左边,可能会被临时消息所掩盖。如果要显示永久信息,要使用statusBar->addPermanentWidget()函数来添加一个如QLabel一样的可以显示信息的部件,它会生成在状态栏的最右端,不会被临时消息所掩盖。

14、关于随机数,在Qt中是使用qrand()和qsrand()两个函数实现的。在使用qrand()函数产生随机数之前,一般要使用qsrand()函数为其设置初值,如果不设置初值,那么每次运行程序,qrand()都会产生相同的一组随机数。为了每次运行程序时,都可以产生不同的随机数,我们要使用qsrand()设置一个不同的初值。

JDK6/mq612 / public class TrayDemo extends JFrame { private JPanel pane = null; private JButton button = null; // 启动托盘图标的按钮 private JLabel label = null; // 用来显示系统是否支持托盘的信息 private TrayIcon trayIcon = null; // 托盘图标 private SystemTray tray = null; // 本 *** 作系统托盘的实例 public TrayDemo() { super("Java160托盘技术演示"); try { // 将LookAndFeel设置成Windows样式 UIManagersetLookAndFeel("comsunjavaswingplafwindowsWindowsLookAndFeel"); } catch (Exception ex) { exprintStackTrace(); } pane = new JPanel(); button = new JButton("缩小到托盘"); buttonsetEnabled(false); label = new JLabel("本 *** 作系统不支持托盘"); paneadd(label); paneadd(button); if(SystemTrayisSupported()){ // 如果 *** 作系统支持托盘 thistray(); } thisgetContentPane()add(pane); thissetDefaultCloseOperation(JFrameEXIT_ON_CLOSE); thissetSize(300, 200); thissetVisible(true); } / 托盘相关代码 / private void tray(){ labelsetText("本 *** 作系统支持托盘"); buttonsetEnabled(true); tray = SystemTraygetSystemTray(); // 获得本 *** 作系统托盘的实例 ImageIcon icon = new ImageIcon("images/icongif"); // 将要显示到托盘中的图标 PopupMenu pop = new PopupMenu(); // 构造一个右键d出式菜单 MenuItem show = new MenuItem("显示窗口"); MenuItem exit = new MenuItem("退出演示"); MenuItem author = new MenuItem("Author"); / TrayIcon有三个构造 TrayIcon(Image image) 用“图标”来构造 TrayIcon(Image image, String tooltip) 用“图标”和“ToolTip”构造 TrayIcon(Image image, String tooltip, PopupMenu popup) 用“图标”,“ToolTip”,“d出菜单”来构造一个托盘图标 / trayIcon = new TrayIcon(icongetImage(), "Java160托盘技术演示", pop); // 点击本按钮后窗口被关闭,托盘图标被添加到系统的托盘中 buttonaddActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { trayadd(trayIcon); // 将托盘图标添加到系统的托盘实例中 setVisible(false); // 使窗口不可视 } catch (AWTException ex) { exprintStackTrace(); } } }); / 添加鼠标监听器,当鼠标在托盘图标上双击时,默认显示窗口 / trayIconaddMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if(egetClickCount()==2){ // 鼠标双击 trayremove(trayIcon); // 从系统的托盘实例中移除托盘图标 setVisible(true); // 显示窗口 } } }); showaddActionListener(new ActionListener() { // 点击“显示窗口”菜单后将窗口显示出来 public void actionPerformed(ActionEvent e) { trayremove(trayIcon); // 从系统的托盘实例中移除托盘图标 setVisible(true); // 显示窗口 } }); exita

对于经常喜欢将文件放置在电脑桌面的朋友来说,最佳的优化方案是将桌面路径更改为非系统盘,因为桌面文件默认是存放在系统盘,电脑开关机都会扫描到,文件过多会影响速度,而我们通过修改Win10桌面文件路径,就可以很好的解决这一问题。那么Win10桌面路径怎么改接下来小编为您带来Win10深度优化之桌面文件路径更改教程。 Win10桌面文件路径更改教程方法步骤如下: 一、首先进入Win10这台电脑,然后进入系统盘,然后依次进入用户--系统账号文件夹--然后找到桌面文件夹,然后在桌面文件夹上鼠标右键,在d出的菜单中选择打开属性,如下图所示。 注 由于笔者电脑安装了Win81/Win10双系统,Win10是安装在H盘,因此以上系统盘进入的是H盘,一般来说,如果大家只安装了一个系统,那么系统盘默认是C盘。 二、在打开的桌面属性对话框中,先切换到选项卡中的位置,然后点击底部的移动,如下图所示: 三、在d出的“选择一个目标”对话框中,我们点击左侧的这台电脑,然后选择一个非系统盘中的“桌面”文件夹,如下图所示。 注:笔者将Win10桌面路径更改为了非系统的E盘下,大家可以事先在E盘建立一个“桌面”文件夹,然后在第三步这里,直接选择即可,也可以在选择的时候,临时创建一个。 四、完成目标文件夹选择后,点击底部的确定就可以完成Win10桌面路径的更改了,如下图所示。 通过以上大致四个步骤,我们就成功的将Win10桌面路径由系统盘转移到了其他非系统盘,以后在桌面存放的文件,都不是在系统盘,这样可以有利于的减少系统盘压力,提升电脑开关机速度,属于深度电脑优化小技巧。

以上就是关于如何在QT中读取串口数据全部的内容,包括:如何在QT中读取串口数据、qt编程问题、Qt 怎么获取系统拖盘的鼠标进入和离开事件等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9446047.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-28
下一篇2023-04-28

发表评论

登录后才能评论

评论列表(0条)

    保存