【技术应⽤】⽤QT编写的视频监控界⾯
本例是⽤QT编写的视频监控界⾯。由主窗⼝的两个按钮可以分别调⽤观看两个摄像头的视频内容。加主线程共3个线程。两个视频显⽰窗⼝⽤Qtimer 来控制。视频图⽚显⽰使⽤lable控件。此程序主要讲解本地图⽚多线程传输,暂时不⽤多次刷新显⽰连续帧。待USB冲突解决后⽅可实现。
Client端:
⽤QT设计界⾯。其中包括main.cpp, mainWindow_main.cpp, video_thread1.cpp, video_thread2.cpp, video_client.cpp及其对应的*.h⽂件。
1.mainWindow_main.cpp
此为主窗⼝的功能实现代码。该主窗⼝包含两个pushButton, 点击按钮pushBtn_video1则调⽤video_thread1.cpp, 点击按钮pushBtn_video2则调⽤video_thread2.cpp.
该mainWindow_main.cpp功能实现很简单,只是实现⼀个窗⼝调⽤。
void mainWindow_main::on_pushBtn_video1_clicked()
{
MainWindow_thread1 *show_video1 = new MainWindow_thread1();
show_video1->show();
}
void mainWindow_main::on_pushBtn_video2_clicked()
{
MainWindow_thread2 *show_video2 = new MainWindow_thread2();
show_video2->show();
}
2. video_thread1.cpp和 video_thread2.cpp
此为点击主界⾯两个按钮时出现的两个窗⼝所执⾏的代码。这两个⽂件的代码很相似,只⽤全局变量所标识的线程号thread_Num有所不同。
程序执⾏伊始,设全局变量temp=0。temp为开启 / 关闭视频的全局标识变量。
update( )。便于随时刷新,它可⾃动调⽤paint事件重绘显⽰屏幕。
1)编写单击开始按钮的槽on_bottonStart1_clicked( )。
{temp=0;//如果是stop按钮的话,就设为1
thread_Num=1;
thread1.video_start(temp, thread_Num);}
线程2同理。只需改动thread_Num为2即可。
2)编写paint事件paintEvent(QPaintEvent *e)
如果不⽤QT的事件机制来画图的话,图⽚是不能被正常显⽰在lable中的。
QPainter paint(this);
QImage image("init_thread1.jpg");//显⽰传送过来的图⽚
paint.drawImage(QRect(0,0,640,480),image);
QWidget::paintEvent(e);
3.video_start( int temp, int thread_Num )的实现
(⾃⼰定义⼀个新类video_client,在video_thread1.cpp和 video_thread2.cpp中分别定义⼀个对象,然后在video_thread1.cpp 和 video_thread2.cpp中使⽤。)
1)先判断temp的值。为1,跳出;为0,向下执⾏。
2)struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_ANY);//链接本机
//sin.sin_addr.s_addr = inet_addr("192.168.47.23");//指定的服务器端地址(但服务器端不⽤指明客户端地址)
if(thread_Num == 1)
{sin.sin_port = 8000;}
else
thread技术{sin.sin_port = 8001;}
3)sockfd=socket(AF_INET, SOCK_STREAM, 0);// 建⽴socket
4)::connect(sockfd, (sockaddr *)&sin, sizeof(sin));//请求连接,对应server的accept( )
5)新建init_thread1.jpg和init_thread1.jpg,⽤于写⼊接收到的图⽚数据。
if(thread_Num==1)
{fd_frame = fopen("init_thread1.jpg","wb"); }
else
{fd_frame = fopen("init_thread2.jpg","wb");}
开始数据传输:
1) 接收所传图⽚的⼀共需要传送的次数times;
2) 做times次循环;
3) ::memset( buff, 0, 1024 ); 不把暂存数组清零会出错误;
4) 每次接收1024字节len1 = recv(sockfd, buff, 1024, 0);
5) 每次接收后在传输过程中,接收⼀次,就顺序写⼊init_thread1.jpg和init_thread1.jpg
len = fwrite(buff, 1024, 1, fd_frame);
6)给server端应答信号:len2 = send(sockfd, buf, 10,0);
7)同理接收最后的⼩于1024字节的数据(即前⾯取余所得值)。
关闭写⼊图⽚的指针fclose( fd_frame );
关闭socket。即::close( sockfd );
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论