QT 常用事件及QPainter
QWidget提供的事件处理函数
- 重载event
- bool event(QEvent *e)
- 返回true处理下一个事件
- 返回false本事件的下一个处理函数
- 以及一些常用事件
QEvent提供的属性及函数
QEvent 子类QInputEvent
- 示例(针对按键事件的两种方式 event函数 需要事件类型转换,或者重载自带的按键处理函数):
QEventTest::QEventTest(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
//this->setMouseTracking(true);
}
bool QEventTest::event(QEvent *ev)
{
if (ev->type() == QEvent::KeyPress)
{
QKeyEvent *ke = static_cast<QKeyEvent*>(ev);
if (ke->key() == 'A')
{
//自动连按事件,不处理
if (!ke->isAutoRepeat())
qDebug() << "aaaaaaaaaaaaaaaaaaa";
return true;
}
}
return QWidget::event(ev);
}
void QEventTest::keyPressEvent(QKeyEvent *ev)
{
//自动连按事件,不处理
if (ev->isAutoRepeat()) return;
if (ev->key() == Qt::Key_F1)
{
qDebug() << "Key_F1";
}
qDebug() << "keyPressEvent = " << ev->key();
}
//键盘松开
void QEventTest::keyReleaseEvent(QKeyEvent *ev)
{
//自动连按事件,不处理
if (ev->isAutoRepeat()) return;
qDebug() << "keyReleaseEvent = " << ev->key();
}
QMouseEvent
- 鼠标坐标:
- 按键状态:
- QWidget提供的重载函数:
- 光标样式
- 示例:
bool WidgetDemo::event(QEvent *ev)
{
if (ev->type() == QEvent::MouseButtonPress)
{
QMouseEvent *me = static_cast<QMouseEvent*> (ev);
相对坐标
qDebug() << "LocalPos " << me->x() << ":" << me->y();
//程序坐标
qDebug() << "windowPos " << me->windowPos().x() << ":" << me->windowPos().y();
//屏幕坐标
qDebug() << "screenPos " << me->screenPos().x() << ":" << me->screenPos().y();
//本地坐标转全局(屏幕坐标)
QPoint gpos = mapToGlobal(me->pos());
qDebug() << "mapToGlobal " << gpos.x() << ":" << gpos.y();
//获取鼠标的屏幕坐标
qDebug() << "QCursor " << QCursor::pos().x() <<":" << QCursor::pos().y();
//鼠标按键事件
if (me->buttons() & Qt::LeftButton)
{
qDebug() << "LeftButton";
setCursor(Qt::ArrowCursor);
}
if (me->buttons() & Qt::RightButton)
{
qDebug() << "RightButton";
//右键菜单
menu.exec(gpos);
}
if (me->buttons() & Qt::MidButton)
{
qDebug() << "MidButton";
}
//左右键同时按下
if ( (me->buttons() & Qt::LeftButton) && (me->buttons() & Qt::RightButton) )
{
qDebug() << "LeftButton&RightButton";
//鼠标图标替换 -1 -1 热点中间
QPixmap pix("cursor.png");
QCursor cur = QCursor(pix, -1, -1);
setCursor(cur);
}
}
return QWidget::event(ev);
}
- 事件重载测试:
virtual void enterEvent(QEvent *event)
{
qDebug() << "enterEvent";
}
virtual void leaveEvent(QEvent *event)
{
qDebug() << "leaveEvent";
}
virtual void mouseDoubleClickEvent(QMouseEvent *event)
{
qDebug() << "mouseDoubleClickEvent "<<event->pos().x()<<":" << event->pos().y();
}
virtual void mouseMoveEvent(QMouseEvent *event)
{
qDebug() << "mouseMoveEvent " << event->pos().x() << ":" << event->pos().y();
}
virtual void mousePressEvent(QMouseEvent *event)
{
qDebug() << "mousePressEvent " << event->pos().x() << ":" << event->pos().y();
}
virtual void mouseReleaseEvent(QMouseEvent *event)
{
qDebug() << "mouseReleaseEvent " << event->pos().x() << ":" << event->pos().y();
}
窗口大小改变事件
- 方式1:
bool WidgetDemo::event(QEvent *e)
{
if (e->type() == QEvent::Resize)
{
QResizeEvent *re = static_cast<QResizeEvent *>(e);
qDebug() << "Resize old" << re->oldSize().width() << ":" << re->oldSize().height()
<< " new size" << re->size().width() << ":" << re->size().height();
}
return QWidget::event(e);
}
- 方式2:
void resizeEvent(QResizeEvent *ev)
{
ui.label->resize(width(), height() - ui.label->y());
}
QT图像绘制QPainter
- 参考官方文档:QPainter QPen QBrush
- 参考:QT自绘控件_深之JohnChen的专栏-CSDN博客_qt自绘控件
- Qpen示例:
QPainter示例
void TestQPainter::paintEvent(QPaintEvent *ev)
{
//设置绘制设备 (widget)
QPainter p(this);
p.begin(this);
//设置画笔颜色
p.setPen(QColor(255, 0, 0, 150));
//设置字体
//p.setFont(QFont(QStringLiteral("黑体"), 30));
QFont font = ui.fontComboBox->currentFont();
font.setPixelSize(30);
p.setFont(font);
//绘制文本
p.drawText(100, 100, QStringLiteral("测试的显示文字"));
//绘制线
//设置画笔样式
QPen pen;
//实线
pen.setStyle(Qt::SolidLine);
//线粗
pen.setWidth(30);
//线刷子
pen.setBrush(Qt::red);
//刷子为图片
pen.setBrush(QBrush(QImage("test.jpg")));
//结尾端样式
pen.setCapStyle(Qt::RoundCap);
//连接处样式
pen.setJoinStyle(Qt::RoundJoin);
p.setPen(pen);
p.drawLine(QLine(0, 0, 300, 300));
p.drawLine(QLine(300, 300, 600, 0));
QVector<QLine> lines;
lines.push_back(QLine(0, 0, 350, 350));
lines.push_back(QLine(350, 350, 0, 450));
lines.push_back(QLine(0, 450, 550, 550));
p.drawLines(lines);
p.end();
}
QImage 创建 清空和空判断
- 对齐问题,每行的宽度是4的倍数:
- 示例:
testQImage::testQImage(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
img = QImage(1280, 720, QImage::Format_RGBA8888);
//填入颜色
img.fill(QColor(255, 0, 0, 200));
//遍历设置颜色
uchar *data = img.bits();
//假定已对齐,不对齐就出错
for (int i = 0; i < img.width(); i++)
{
for (int j = 0; j < img.height()/2 ; j++)
{
data[j*img.width() * 4 + i * 4] = 0;// R
data[j*img.width() * 4 + i * 4+1] = 255;// G
data[j*img.width() * 4 + i * 4+1] = 0;// B
data[j*img.width() * 4 + i * 4+1] = 255;// A
}
}
for (int i = img.width()/2; i < img.width(); i++)
{
for (int j = 0; j < img.height(); j++)
{
img.setPixelColor(i, j, QColor(0, 0, 0, 255));
}
}
}
void testQImage::paintEvent(QPaintEvent *ev)
{
QPainter p(this);
if (!img.isNull())
p.drawImage(0,0,img);
}