1.重写键盘按下事件,
函数: void keyPressEvent(QKeyEvent *event) /*** 按键按下事件 ***/
代码:
void keyPressEvent(QKeyEvent *event) /*** 按键按下事件 ***/{qDebug() << "按下的按键个数:" << event->count() << endl;qDebug() << "按下的按键码:" << event->key() << endl; // 按键码需要参考 Qt:Key 按键枚举表qDebug() << "按下的按键字符:" << event->text() << endl; // 按下按键的字符}
2.重写键盘 按键松开事件
函数: void keyReleaseEvent(QKeyEvent *event) /*** 按键松开事件 ***/
void keyReleaseEvent(QKeyEvent *event) /*** 按键松开事件 ***/{qDebug() << "松开的按键个数:" << event->count() << endl;qDebug() << "松开的按键码:" << event->key() << endl; // 按键码需要参考 Qt:Key 按键枚举表qDebug() << "松开的按键字符:" << event->text() << endl; // 按下按键的字符}
3.重写 鼠标按下事件
函数:void mousePressEvent(QMouseEvent *event) /*** 鼠标按下事件 ***/
代码:
void mousePressEvent(QMouseEvent *event) /*** 鼠标按下事件 ***/{/***** 案例:我的鼠标有 左键,右键,前进键和后退键 ****/switch ((unsigned int)event->button()) { // 获取按下的按键case Qt::LeftButton:mouse_flag = true;qDebug() << "鼠标左键按下" << endl;break;case Qt::RightButton:qDebug() << "鼠标右键按下" << endl;//Menu->exec(QCursor::pos()); //QCursor::pos()获取鼠标的全局坐标//Menu->exec(event->globalPos()); //event->globalPos()获取鼠标的全局坐标break;case Qt::BackButton:qDebug() << "鼠标后退键按下" << endl;break;case Qt::ForwardButton:qDebug() << "鼠标前进键按下" << endl;break;case Qt::MiddleButton:qDebug() << "鼠标中间滚轮键按下" << endl;break;}}
4.重写 鼠标松开事件
函数: void mouseReleaseEvent(QMouseEvent *event) /*** 鼠标松开事件 ***/
代码:
void mouseReleaseEvent(QMouseEvent *event) /*** 鼠标松开事件 ***/{/***** 案例:我的鼠标有 左键,右键,前进键和后退键 ****/switch ((unsigned int)event->button()) { // 获取松开的按键case Qt::LeftButton:mouse_flag = false;qDebug() << "鼠标左键松开" << endl;break;}}
5.重写鼠标双击事件
函数:void mouseDoubleClickEvent(QMouseEvent *event); /*** 鼠标双击事件 ***/
代码:
void mouseDoubleClickEvent(QMouseEvent *event)//鼠标双击事件{qDebug()<<"鼠标双击事件";}
6.重写鼠标移动事件
函数:void mouseMoveEvent(QMouseEvent *event); /*** 鼠标移动事件 ***/
代码:
因为要用到 this 所以我们在 .h 文件里面声明,.cpp 文件里面实现 .
void Widget::mouseMoveEvent(QMouseEvent *event)
{/***** 思考:为什么需要按键按下并鼠标移动才触发时间 ? ***** QWidget 默认关闭焦点,所以需要打开焦点* 使用这个函数:this->setMouseTracking(true); // 设置鼠标焦点使能* ***********************************************/if(this->mouse_flag){qDebug() << "全局坐标:" << event->globalPos() << endl;//全局变量是整个电脑屏幕 处在的位置qDebug() << "局部坐标:" << event->localPos() << endl;//局部变量是自己打开的窗口的处在的位置}
}
7.重写鼠标中间/滚轮事件
函数: void wheelEvent(QWheelEvent *event) /*** 鼠标中间/滚轮事件 ***/
代码:
void wheelEvent(QWheelEvent *event) /*** 鼠标中间/滚轮事件 ***/{/**** 获取滚动的距离 ******* QPoint angleDelta()* ******************************************************/QPoint point = event->angleDelta(); //获取距离qDebug() << "距离:" << point.y() << endl;qDebug() << "方向:" << (point.y() >= 0 ? "向前" : "向后") << endl;}
8.重写定时器事件
函数: void timerEvent(QTimerEvent *)
代码:
#include //定时器事件
public: /*** 定时器事件 ****/void timerEvent(QTimerEvent *){static int count = 0;//qDebug() << "闹钟的数量:" << ++count << endl;}
启动定时器事件的 代码
/***** 定时器事件 *******/this->startTimer(1000); // 1000 毫秒 = 1秒钟 , 计数到1秒则触发事件 timerEvent
9. 重写绘图事件 (画圆,画点,画线,)
函数: void paintEvent(QPaintEvent *) /**** 绘图事件 ***/
代码:
void paintEvent(QPaintEvent *) /**** 绘图事件 ***/{QPainter p(this);/***** 画刷 ********************************/QBrush Brush = p.brush(); // 获取画家手上的刷子Brush.setColor(QColor(255,0,0));p.setBrush(Brush);/***** 画笔 ********************************/QPen Pen = p.pen();Pen.setColor(QColor(0,255,0)); //设置画笔颜色Pen.setWidth(4); //设置画笔大小Pen.setStyle(Qt::DashLine); //设置画笔样式p.setPen(Pen);p.setFont(QFont("宋体",16));/**** 绘制形状 ****/p.drawPoint(200,200); //画点p.drawLine(QPoint(100,100),QPoint(200,200)); //画线p.drawRect(100,100,100,100); //画矩形 drawRect(int x, int y, int w, int h)p.drawEllipse(QPoint(150,150),50,50); //画圆 (const QPoint ¢er, int rx, int ry)p.drawImage(QPoint(200,200),QImage("://QQ图片20221125090254.png"));//画一张图片Pen.setColor(QColor(0,0,255)); //设置画笔颜色p.setPen(Pen);p.setFont(QFont("宋体",16));p.drawText(QPoint(300,20),"老师的牛逼");//形成一个文本框,里面写了 文字}
#include
#include
1. 定义指针的变量 QTimer *Timer1;//定时器类对象
2.实列化对象 Timer1 = new QTimer(this);
3.建立信号连接 等定时器到了时间就, 发出信号 connect(Timer1,SIGNAL(timeout()),this,SLOT(slot_Timer1()));
4. 打开定时器 Timer1->start(100); // 100毫秒 = 0.1 毫秒 , 计数到0.1秒则触发 timeout() 信号
1.给控件加上 一个捕获事件的能力,(本来捕获事件的能力都是 widget 界面的)
ui->progressBar->grabKeyboard();//设置键盘捕获事件
2.给控件安装事件过滤器
/*** 将控件安装事件过滤器 ***/ui->progressBar->installEventFilter(this);;; //ui->progressBar 进度条控件的事件交给 Widget 去处理
3.设置控件获取焦点 (因为平时焦点都是在 界面上 ,而我们需要让 控件获取焦点的能力)
所谓的焦点窗口,指的是当前时刻拥有键盘输入的窗口。
补充两个概念,活动窗口和前景窗口。活动窗口,指的是当前时刻与用户进行交互的窗口;前景窗口,指的是显示器最顶层窗口,前景窗口永远在其他窗口上方,不被遮挡。
设置焦点可以让应用更便捷。比如当你打开百度主页或其他带有编辑框的页面时,不需要先用鼠标点击编辑框就可以直接输入文字等信息到其中。这就是由于搜索框设置了焦点。
这就是说 有了焦点,我们把鼠标放到控件上,窗口就知道我们操作的是 控件,假如没有焦点,那么窗口就不知道。
ui->progressBar->setFocus();//控件获取焦点
4.重写 事件过滤器
函数:bool eventFilter(QObject *watched, QEvent *event); /**** 事件过滤 ****/
代码:
#include /*** 调试类 ***/
#include /*** 进度条类 ***/
#include /*** 按键事件类 ****/
/*** 注意事项:没有处理就返回false,处理了就返回true 完成了也可以返回 false 可以让下一级来操作 ***/
bool Widget::eventFilter(QObject *watched, QEvent *event)
{if(watched == ui->progressBar) // 说明是我的 进度条控件 发出的事件{QProgressBar *ProgressBar = (QProgressBar *)watched;//把类型强转/*** QEvent 事件基类中有一个 type() 函数获取事件的类型,可以参考 QEvent::Type 枚举表 ****/if(event->type() == QEvent::KeyPress) /*** 按键事件 ****/{qDebug() << "进度条控件发出事件" << endl;QKeyEvent *KeyEvent = (QKeyEvent *)event;qDebug() << "按下的按键:" << KeyEvent->text() << endl;int x = ProgressBar->x();int y = ProgressBar->y();switch ((unsigned int)KeyEvent->key()) {case Qt::Key_Up:ProgressBar->move(x,y-10);return true;case Qt::Key_Down:ProgressBar->move(x,y+10);return true;case Qt::Key_Left:ProgressBar->move(x-10,y);return true;case Qt::Key_Right:ProgressBar->move(x+10,y);return true;}}}return false; /*** 没有处理 ***/
}
1.在学习UDP的时候,我们需要在
2. 学习UDP 的建立步骤
1.头文件 : #include
#include
2. 建立UDP 网络套接字对象 QUdpSocket *UdpSocket;
3.实列话对象 UdpSocket = new QUdpSocket(this);
4. 知道 UDP 的函数 并且运用
/******************* QUdpSocket 类 ******************* 绑定:* ip地址和端口号 : bool bind(const QHostAddress &address, quint16 port = 0, BindMode mode = DefaultForPlatform);* 默认本地ip: bool bind(quint16 port = 0, BindMode mode = DefaultForPlatform);* 发送:qint64 writeDatagram(const QByteArray &datagram, const QHostAddress &host, quint16 port)* 接收:qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *host = Q_NULLPTR, quint16 *port = Q_NULLPTR);* 信号函数:* 套接字有数据可读 : void readyRead()* **************************************************/
5. UDP 绑定 IP 和端口号
我才用的 是 默认本地ip 的绑定
void Udp::slot_pushButton_bind()
{QString ip = ui->lineEdit_ip_bind->text();//获取自己写的 ip 地址int port = ui->lineEdit_port_bind->text().toInt();//获取端口号bool ok = false;//判断自己是否写了 ip 地址if(ip.isEmpty() == true){ok = UdpSocket->bind(port);//采用默认 IP地址绑定。}else{ok = UdpSocket->bind(QHostAddress(ip),port);//采取 自己写的 ip 地址和 端口号 来绑定}if(ok == true){ui->pushButton_bind->setText("绑定成功");ui->pushButton_bind->setEnabled(false);}else{QMessageBox::warning(this,"绑定警告","绑定失败,端口号以被使用");//警告消息对话框}
}
6. UDP 发送数据
函数: writeDatagram(参数1,参数2,参数3)
参数1,数据。 (类型需要转 UTF-8)
参数2 , 目标用户的 ip
参数3 , 目标用户的port
代码:
void Udp::slot_pushButton_send()
{QString ip = ui->lineEdit_ip_send->text();//获取 目标 的IPint port = ui->lineEdit_port_send->text().toInt();获取 目标的port QString text = ui->textEdit_write->toPlainText();// 获取发送的内容UdpSocket->writeDatagram(text.toUtf8(),QHostAddress(ip),port);//发送数据
}
7.UDP 接收信息,
1. 首先建立连接
connect(UdpSocket,SIGNAL(readyRead()),this,SLOT(slot_UdpSocket_readyRead()));
参数1 : UDP 的指针, 参数2 有数据可以接收的信号,
参数3 界面指针 参数4 自己写的槽函数,接收数据
2.直接接收数据
void Udp::slot_UdpSocket_readyRead()
{char *buf = new char[1024]; /*** 申请空间 ***/memset(buf,0,1024);//清除空间,防止有脏数据QHostAddress host; //对方的主机quint16 port; //对方的端口UdpSocket->readDatagram(buf,1024,&host,&port);//我这里有一个疑问,接收的空间 ,没有数据大咋办,一次接收后,还会有第二次接收吗??ui->textEdit_read->append(buf);delete buf; /*** 释放空间 ***/
}
1.头文件
#include
#include
2. 建立TCP 网络套接字对象 TCPsever *sevser
3.实列话对象 sevser = new TCPsever;
4. 知道 TCP 服务器 的函数 并且运用
/********** QTcpServer 服务器类 ******** ①绑定监听 : bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)* ②等待响应|用户连入信号 : void newConnection()* ③接入已挂起的客户端 : QTcpSocket *QTcpServer::nextPendingConnection()* **********************************************************************************/
/********** QTcpSocket 套接字类 ********* 连接: void connectToHost(const QHostAddress &address, quint16 port, OpenMode openMode = ReadWrite)* 断开: void disconnectFromHost()* 读取:* QByteArray read(qint64 maxSize) 指定读取长度* QByteArray readAll() 读取全部内容* 写入:* qint64 write(const char *data) 发送字符串内容* qint64 write(const QByteArray &byteArray) 发送QByteArray内容* 信号:* void readyRead() 有数据可读发出信号* void connected() 连接成功信号* void disconnected() 断开连接信号* 数据函数:* qint64 QAbstractSocket::readBufferSize() 缓存区大小* ***** 缓冲区可读内容长度** 获取IP地址:QHostAddress peerAddress() const* 获取端口号:quint16 peerPort() const* ***************************************************************************************/
/********************* QHostAddress 类 **************************************************** QHostAddress::Any 枚举值,双栈协议* QString QHostAddress::toString() const 的ip地址转字符串* **************************************************************************************/
5. 申请服务器TCP类空间 QTcpServer* TcpServer = new QTcpServer(this);
6. TCP 绑定 ip 和端口号
函数 :listen(QHostAddress::Any,port);
参数1 QHostAddress类提供一个IP地址。
QHostAddress类 这个类提供一种独立于平台和协议的方式来保存IPv4和IPv6地址。
参数2 这个电脑可以绑定的 端口号
代码:
void TCPsever::slot_pushButton_bind()
{QString ip = ui->lineEdit_ip->text();int port = ui->lineEdit_port->text().toInt();TcpServer->listen(QHostAddress::Any,port); //双栈绑定
}TCPsever::~TCPsever()
{delete ui;
}
7.为客户的连接 建立信号连接 (目的 当有客户连接的时候,我们可以知道并且获取 客户的 ip 和 端口号 )
connect(TcpServer,SIGNAL(newConnection()),this,SLOT(slot_TcpServer()));
参数1 TCP类空间的指针 , 参数2 用户连接信号
8.读取数据 建立连接
connect(TcpSocket,SIGNAL(readyRead()),this,SLOT(slot_TcpSocket_readyRead()));
参数1 TCP类空间的指针 参数2 有数据可以读取的信号函数
9.发送过来的数据读取
代码:
void TCPsever::slot_TcpSocket_readyRead()
{QTcpSocket *TcpSocket = (QTcpSocket *)sender();QByteArray buf = TcpSocket->readAll();ui->textEdit->append(buf);
}
这里只有函数可以讲
1.建立对象,并且实列化对象 QTcpSocket *TcpSocket; /*** TCP套接字类指针 **/
TcpSocket = new QTcpSocket(this);
2.关于客户端的函数,
/********** QTcpSocket 套接字类 ********* 连接: void connectToHost(const QHostAddress &address, quint16 port, OpenMode openMode = ReadWrite)* 断开: void disconnectFromHost()* 读取:* QByteArray read(qint64 maxSize) 指定读取长度* QByteArray readAll() 读取全部内容* 写入:* qint64 write(const char *data) 发送字符串内容* qint64 write(const QByteArray &byteArray) 发送QByteArray内容* 信号:* void readyRead() 有数据可读发出信号* void connected() 连接成功信号* void disconnected() 断开连接信号* 数据函数:* qint64 QAbstractSocket::readBufferSize() 缓存区大小* ***** 缓冲区可读内容长度* ***************************************************************************************/
3.连接服务端
函数:void connectToHost(const QHostAddress &address, quint16 port, OpenMode openMode = ReadWrite)
参数1 IP 参数2 端口号
代码:
void TCPclient::slot_pushButton_connect()
{QString ip = ui->lineEdit_ip->text();//获取要连接的服务器的 ip int port = ui->lineEdit_port->text().toInt();//获取要连接的服务器的 端口号TcpSocket->connectToHost(QHostAddress(ip),port);//连接服务器
}
4. 为连接服务器成功做准备, 主要是建立一个信号连接,来知道,与服务器连接成功了
connect(TcpSocket,SIGNAL(connected()),this,SLOT(slot_TcpSocket_connected()));
第二个参数 是 一个连接服务器成功的信号,
代码:
void TCPclient::slot_TcpSocket_connected()
{ui->pushButton_connect->setText("连接成功");ui->pushButton_send->setEnabled(true); //使能发送按钮
}
5.为服务器断开连接做准备, 主要是建立一个信号连接,来知道,与服务器服务器断开连接了
connect(TcpSocket,SIGNAL(disconnected()),this,SLOT(slot_TcpSocket_disconnected()));
代码:
void TCPclient::slot_TcpSocket_disconnected()
{ui->pushButton_connect->setText("已断开连接");ui->pushButton_send->setEnabled(false); //使能发送按钮
}
6.客户端向服务端发送数据
函数:write(text.toUtf8());
代码:
void TCPclient::slot_pushButton_send()
{QString text = ui->textEdit_send->toPlainText();//读取要发送的数据TcpSocket->write(text.toUtf8());//向服务器发送数据
}
7.客户端 读取 服务端发送的数据
建立连接
connect(TcpSocket,SIGNAL(readyRead()),this,SLOT(slot_TcpSocket_readyRead()));//和之前一样
代码:
void TCPclient::slot_TcpSocket_readyRead()
{QByteArray buf = TcpSocket->readAll();//读取数据ui->textEdit_read->append(buf);
}