QT组件的事件

一.所有组件的事件
对事件的响应是通过信号与槽调用
事件中根据事件触发的条件发出不同的信号。
比如:鼠标事件发出clicked与dblclicked toggle等信号
QT中事件是怎么实现的?
QT把事件自己定义成固定的virtual保护函数.
这些函数自动被系统调用。
1.paintEvent
案例:
1.覆盖QWidget的paintEvent
绘制gdi(Graphics Draw Interface)
2.覆盖QPushButton的paintEvent


2.mouseEvent
3.keyEvent

例1:在窗体上绘制扇形,扇形的嘴张开关闭

PaintWidget.h

#ifndef PAINT_WIDGET_H
#define PAINT_WIDGET_H
#include <QWidget>
#include <QPaintEvent>
#include <QTimer>
class PaintWidget : public QWidget
{
Q_OBJECT
private:
	int mouth;
	bool isopen;//张嘴还是闭嘴
	QTimer timer;
protected:	
	virtual void paintEvent(QPaintEvent *e);
public:
	PaintWidget();
public slots:
	void openMouth(); 	
};
#endif

PaintWidget.cpp

#include "PaintWidget.h"
#include <QPainter>
#include <QImage>
#include <QPixmap>
#include <QBitmap>
#include <QPen>
#include <stdio.h>
void PaintWidget::openMouth()
{
	//printf("OK\n");
	if(isopen)
	{
		mouth+=1;
		if(mouth>=30)
		{
			mouth=30;
			isopen=!isopen;
		}
	}
	else
	{
		mouth-=1;
		if(mouth<=0)
		{
			mouth=0;
			isopen=!isopen;
		}
	}
	repaint();//强制调用paintEvent事件函数
} 
PaintWidget::PaintWidget()
	:mouth(30),isopen(false){
	timer.setInterval(100);
	timer.start();
	connect(&timer,SIGNAL(timeout()),
		this,SLOT(openMouth()));
}
void PaintWidget::paintEvent(QPaintEvent *e)
{
	QPainter g(this);//this参数指定绘制目标
	g.drawPie(100,100,100,100,mouth*16,
		(360-2*mouth)*16);
	/*
	QPoint p[3];
	p[0].setX(10);
	p[0].setY(10);
	p[1].setX(300);
	p[1].setY(10);
	p[2].setX(145);
	p[2].setY(200);
	*/
	/*
	QImage  img("ok.png");
	QPixmap map("00.PNG");
	QPixmap bit=map.createMaskFromColor(QColor(255,255,255),Qt::MaskInColor);
	QBrush br(QColor(0,255,0));
	QPen  pen(br,3);
	*/
	//进行绘制工作 
	//1.产生绘制对象QPainter	
	//2.设置绘制对象的属性	
	//3.进行绘制:图形,图像与字符串
	//g.setClipRect(0,0,100,100);
	/*
	g.drawLine(10,10,400,400);
	g.setPen(pen);
	g.drawArc(10,10,300,300,10*16,120*16);
	g.drawChord(100,10,300,300,150*16,45*16);
	//g.drawConvexPolygon(p,3);
	
	//g.drawEllipse(0,0,this->width(),this->height());
	//g.drawPie(10,10,300,300,10*16,120*16);
	g.rotate(30);
	g.setFont(QFont("隶书",45,100));
	g.drawText(100,100,"this is a  maomaochong!");
	//g.drawImage(10,10,img,0,0,300,300);//绘制图像
	map.setMask(bit);
	g.drawPixmap(10,10,36,36,map);
	*/
	
}


main.cpp

#include <QApplication>
#include "PaintWidget.h"
int main(int args,char**argv)
{
	QApplication app(args,argv);
	PaintWidget w;
	w.resize(400,400);	
	w.move((1024-400)/2,(768-400)/2);
	w.show();
	
	return app.exec();
}

main.pro

TEMPLATE=app
SOURCES=main.cpp	\
		PaintWidget.cpp	
HEADERS=PaintWidget.h
CONFIG=release qt
QT=core gui
TARGET=main

例2 按钮事件,并覆盖其绘制方法

如图


DemoPushButton.h

#ifndef DEMO2_PUSHBUTTON_H
#define DEMO2_PUSHBUTTON_H
#include <QPushButton>
#include <QPaintEvent>
#include <QMouseEvent>
class DemoPushButton : public QPushButton
{
private:
	bool israised;
public:
	DemoPushButton(QWidget *parent=NULL);
protected:
	virtual void paintEvent(QPaintEvent *e);
	virtual void enterEvent(QEvent *e);
	virtual void leaveEvent(QEvent *e);	
	virtual void mouseMoveEvent(QMouseEvent *e);
};
#endif

DemoPushButton.cpp

#include  "DemoPushButton.h"
#include <QPainter>
#include <QColor>
#include <QBrush>
#include <QPen>
void DemoPushButton::mouseMoveEvent(QMouseEvent *e)
{
	float w=width();
	float h=height();
	int x=e->x();
	int y=e->y();
	float k=h/w;
	
	if(	y>=-k*x+h/2 &&
		y>= k*x-h/2	&&
		y<= k*x+h/2 &&
		y<=-k*x+3*h/2)
	{
		israised=false;
	}
	else
	{
		israised=true;
	}
	repaint();
}
void DemoPushButton::enterEvent(QEvent *e)
{
	israised=false;
	repaint();
}
void DemoPushButton::leaveEvent(QEvent *e)
{
	israised=true;
	repaint();
}	
	
DemoPushButton::DemoPushButton(QWidget *parent)
	:QPushButton(parent),israised(true)
{	
	setMouseTracking(true);
}
void DemoPushButton::paintEvent(QPaintEvent *e)
{
	//绘制按钮的边界
	int w=width();
	int h=height();
	QColor clrw(255,255,255);
	QColor clrb(0,0,0);
	QBrush brw(clrw);
	QBrush brb(clrb);
	QPen   penw(brw,2);
	QPen   penb(brb,2);
	QPoint pttop(w/2,2);
	QPoint ptbottom(w/2,h-2);
	QPoint ptleft(2,h/2);
	QPoint ptright(w-2,h/2);
	QPainter g(this);
	if(israised){
		g.setPen(penw);
	}
	else{
		g.setPen(penb);
	}	
	g.drawLine(pttop,ptleft);
	g.drawLine(pttop,ptright);
		
	if(israised){
		g.setPen(penb);
	}
	else{
		g.setPen(penw);
	}
	g.drawLine(ptbottom,ptleft);
	g.drawLine(ptbottom,ptright);
}

DemoWidget.h

#ifndef DEMO2_WIDGET_H
#define DEMO2_WIDGET_H
#include <QWidget>
#include "DemoPushButton.h"
class DemoWidget:public QWidget
{
private:
	DemoPushButton *btn;
	DemoPushButton *btn2;
public:
	DemoWidget(QWidget *parent=NULL);
};
#endif

DemoWidget.cpp

#include "DemoWidget.h"
DemoWidget::DemoWidget(QWidget *parent)
	:QWidget(parent)
{
	btn=new DemoPushButton(this);
	btn->resize(200,100);
	btn->move(100,100);
	btn2=new DemoPushButton(this);
	btn2->resize(100,30);
	btn2->move(10,10);
}

main.cpp

#include <QApplication>
#include "DemoWidget.h"
int main(int args,char**argv)
{
	QApplication app(args,argv);
	DemoWidget w;
	w.resize(400,400);
	w.show();
	return app.exec();	
}

main.pro

TEMPLATE=app
SOURCES=main.cpp			\
		DemoWidget.cpp		\
		DemoPushButton.cpp
HEADERS=DemoWidget.h		\
		DemoPushButton.h	
CONFIG=release qt
QT=core gui
TARGET=main




QPainter类:
函数分成:
属性函数
背景
刷子
遮罩

字体
绘制函数
图形
空心draw****
实心fill****
图像
字符串
变换函数
translate
scale
rotate
shear
2.leaveEvent/enterEvent
3.mouseMoveEvent
4.mousePressEvent/mouseReleaseEvent

5.keyPressEvent/keyReleaseEvent


例3 键盘事件 当输入为字母是文本框显示字母,否则不显示 通过覆盖系统事件实现

Demo3Edit.h

#ifndef DEMO3_EDIT_H
#define DEMO3_EDIT_H
#include <QLineEdit>
#include <QKeyEvent>
class Demo3Edit : public QLineEdit
{
public:
	Demo3Edit(QWidget *p=NULL);
protected:
	void keyPressEvent(QKeyEvent *e); 	
};
#endif

Demo3Edit.cpp

#include "Demo3Edit.h"
#include <cstdio>
using namespace std;
void Demo3Edit::keyPressEvent(QKeyEvent *e)
{
	/*
	printf("%u:%c:%s\n",e->nativeVirtualKey (),e->key(),e->text().data());*/
	int key=e->key();
	if(key>=65 && key<=90 || key==Qt::Key_Backspace)
	{
		QLineEdit::keyPressEvent(e); 
	}
	else
	{
		return;
	}
}
Demo3Edit::Demo3Edit(QWidget *p)
	:QLineEdit(p)
{
}

Demo3Widget.h

#ifndef DEMO3_WIDGET_H
#define DEMO3_WIDGET_H
#include <QWidget>
#include "Demo3Edit.h"
class Demo3Widget : public QWidget
{
private:
	Demo3Edit *edt;
public:
	Demo3Widget(QWidget*p=NULL);
};
#endif

Demo3Widget.cpp

#include "Demo3Widget.h"
Demo3Widget::Demo3Widget(QWidget *p)
	:QWidget(p)
{
	edt=new Demo3Edit(this);
	edt->resize(200,30);
	edt->move(10,10);
}

main.cpp

#include <QApplication>
#include "Demo3Widget.h"
int main(int args,char **argv)
{
	QApplication app(args,argv);
	Demo3Widget w;
	w.resize(400,400);
	w.setVisible(true);
	return app.exec();
}

main.pro

TEMPLATE=app
SOURCES=main.cpp			\
		Demo3Widget.cpp		\
		Demo3Edit.cpp		
HEADERS=Demo3Widget.h		\
		Demo3Edit.h

CONFIG=release qt
QT=core gui
TARGET=main


二.QT结合其他知识点的应用
1.摇奖程序(QT+多线程)
main.pro 项目代码的组织
main.cpp QT程序的框架
dlgyao.h 摇奖的主UI
dlgyao.cpp
|---信号与槽
thyao.h 摇奖的线程

thyao.cpp


thyao.h

#ifndef TH_YAO_H
#define TH_YAO_H
#include <QThread>
class ThYao : public QThread
{
Q_OBJECT
private:
	bool isstop;
public:
	ThYao();	
public :signals:
	void number(const QString &num);
protected:
	virtual  void run();
public slots:
	void control(bool);
		
};
#endif

thyao.cpp

#include "thyao.h"
#include <unistd.h>
#include <cmath>
void ThYao::control(bool b)
{
	isstop=b;
}
ThYao::ThYao():isstop(false)
{
}
void ThYao::run()
{
	int num;
	while(1)
	{
		while(isstop);		
		num=rand()%10000000;
		QString strnum=QString::number(num);
		emit number(strnum);
		
		usleep(10000);		
	}
}

dlgyao.h

#ifndef DLG_YAO_H
#define DLG_YAO_H
#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include "thyao.h"
class DlgYao : public QWidget
{
Q_OBJECT
private:
	QLabel *lblnum;
	QPushButton *btnyao;
	ThYao *th;
	bool isstop;
public:
	DlgYao(QWidget *p=NULL);
public slots:
	void yao();
public: signals:
	void control(bool);			
};
#endif

dlgyao.cpp

#include "dlgyao.h" 
void DlgYao::yao()
{
	isstop=!isstop;
	if(!isstop)
	{
		btnyao->setText("stop");
	}
	else
	{
		btnyao->setText("again");
	}
	emit control(isstop);
}
DlgYao::DlgYao(QWidget *p)
	:QWidget(p),isstop(false)
{
	lblnum=new QLabel(this);
	btnyao=new QPushButton("stop",this);
	resize(300,200);
	move((1024-300)/2,(768-200)/2);
	lblnum->resize(100,30);
	lblnum->move(100,50);
	lblnum->setFrameShape(QFrame::Box);
	
	btnyao->resize(80,30);
	btnyao->move(110,140);
	connect(btnyao,SIGNAL(clicked()),
			this,SLOT(yao()));	
	th=new ThYao;
	connect(th,SIGNAL(number(const QString&)),
			lblnum,SLOT(setText(const QString&)));
	connect(this,SIGNAL(control(bool)),
		th,SLOT(control(bool)));		
	th->start();	
	setVisible(true);
	
}

main.cpp

#include <QApplication>
#include "dlgyao.h" 
int main(int args,char **argv)
{
	QApplication app(args,argv);
	DlgYao dlg;
	return app.exec();
}

main.pro

TEMPLATE=app
SOURCES=main.cpp	\
		dlgyao.cpp	\
		thyao.cpp
HEADERS=dlgyao.h	\
		thyao.h
CONFIG=release qt
QT=core gui
TARGET=main




作业:
1.把大嘴鱼改成线程来实现。
2.摇奖程序独立完成。
3.实现window的钟
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值