1.鼠标键按下
virtual void mousePressEvent (QMouseEvent*);
2.鼠标键弹起
virtual void mouseReleaseEvent (QMouseEvent*);
3.鼠标键双击
virtual void mouseDoubleClickEvent (QMouseEvent*);
4.鼠标键按下的同时移动
virtual void mouseMoveEvent (QMouseEvent*);
触发按键:
Qt::MouseButton QMouseEvent::button (void);
Qt::LeftButton
Qt::MiddleButton
Qt::RightButton
按键状态:
Qt::MouseButtons QMouseEvent::buttons (void);
Qt::LeftButton
#include mouseevent.h
MouseEvent::MouseEvent(QWidget *parent)
: QMainWindow(parent)
{
setWindowTitle(tr(鼠标事件));
statusLabel = new QLabel;
statusLabel->setText(tr(当前位置:));
statusLabel->setFixedWidth(100);
MousePosLabel = new QLabel;
MousePosLabel->setText(tr());
MousePosLabel->setFixedWidth(100);
statusBar()->addPermanentWidget(statusLabel);
statusBar()->addPermanentWidget(MousePosLabel);
this->setMouseTracking(true);
resize(400,200);
}
MouseEvent::~MouseEvent()
{
}
void MouseEvent::mousePressEvent(QMouseEvent *e)
{
QString str=(+QString::number(e->x())+,+QString::number(e->y())+);
if(e->button()==Qt::LeftButton)
{
statusBar()->showMessage(tr(左键:)+str);
}
else if(e->button()==Qt::RightButton)
{
statusBar()->showMessage(tr(右键:)+str);
}
else if(e->button()==Qt::MidButton)
{
statusBar()->showMessage(tr(中键:)+str);
}
}
void MouseEvent::mouseMoveEvent(QMouseEvent *e)
{
MousePosLabel->setText((+QString::number(e->x())+, +QString::number(e->y())+));
}
void MouseEvent::mouseReleaseEvent(QMouseEvent *e)
{
QString str=(+QString::number(e->x())+,+QString::number(e->y())+);
statusBar()->showMessage(tr(释放在:)+str,3000);
}
void MouseEvent::mouseDoubleClickEvent(QMouseEvent *e){}
sendEvent 发出的事件会立即被处理,也就是“同步”执行。
postEvent 发送的事件会被加入事件队列,在下一轮事件循环时才处理,也就是“异步”执行。
sendPostedEvents,是将已经加入队列中的准备异步执行的事件立即同步执行。
QApplicaion::exec()、QMessageBox::exec()都是事件循环。其中前者又被称为主事件循环。QEventLoop::quit()能够终止事件循环。
当事件太多而不能马上处理完的时候,待处理事件被放在一个“队列”里,称为“事件循环队列”。当事件循环处理完一个事件后,就从“事件循环队列”中取出下一个事件处理之。当事件循环队列为空的时候,它和一个啥事也不做的永真循环有点类似,但是和永真循环不同的是,事件循环不会大量占用CPU资源。
事件循环的本质就是以队列的方式再次分配线程时间片。
事件循环是可以嵌套的,一层套一层,子层的事件循环执行exec()的时候,父层事件循环就处于中断状态;当子层事件循环跳出exec()后,父层事件循环才能继续循环下去。
如果某个子事件循环仍然有效,但其父循环被强制跳出,此时父循环不会立即执行跳出,而是等待子事件循环跳出后,父循环才会跳出。
void frmInput2019::sendEvent(quint8 type, const QString &text)
{
if (type == 0) {
//切换中英模式
QMouseEvent mousePress(QEvent::MouseButtonPress, QPoint(0, 0), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
QApplication::sendEvent(ui->labType->isVisible() ? ui->labType : ui->labType2, &mousePress);
} else if (type == 1) {
//隐藏汉字候选面板
QMouseEvent mousePress(QEvent::MouseButtonPress, QPoint(0, 0), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
QApplication::sendEvent(ui->labMore, &mousePress);
} else if (type == 2) {
//删除
QKeyEvent keyPress(QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier, QString());
QApplication::sendEvent(currentWidget, &keyPress);
} else if (type == 3) {
//插入回车符
QKeyEvent keyPress(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier, QString(\n));
QApplication::sendEvent(currentWidget, &keyPress);
} else if (type == 4) {
//插入字符
QKeyEvent keyPress(QEvent::KeyPress, 0, Qt::NoModifier, QString(text));
QApplication::sendEvent(currentWidget, &keyPress);
}
}
bool frmInput2019::eventFilter(QObject *watched, QEvent *event)
{
//qDebug() << TIMEMS << watched << event;
if (watched == this) {
//处理自身拖动
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
//按下的时候记住坐标,移动到鼠标松开的位置
if (event->type() == QEvent::MouseButtonPress) {
if (mouseEvent->button() == Qt::LeftButton) {
mousePressed = true;
mousePoint = mouseEvent->globalPos() - this->pos();
return true;
}
} else if (event->type() == QEvent::MouseButtonRelease) {
mousePressed = false;
return true;
} else if (event->type() == QEvent::MouseMove) {
//bottom为固定的底部禁用拖动
if (mousePressed && position != "bottom") {
this->move(mouseEvent->globalPos() - mousePoint);
this->update();
return true;
}
}
} else if (watched == ui->labMore) {
//打开更多汉字候选面板
if (event->type() == QEvent::MouseButtonPress) {
}
} else if (watched == ui->labType) {
//中英模式切换,由于采用的标签所以在这里处理
if (event->type() == QEvent::MouseButtonPress) {
setInputType(inputType == "english" ? "chinese" : "english");
}
} else if (watched == ui->labType2) {
//固定切换到英文模式
if (event->type() == QEvent::MouseButtonPress) {
setInputType("english");
}
} else if (watched == ui->widgetCn) {
//没有汉字或者按下的地方没有汉字或者当前汉字标签个数过少都不用继续
if (pinyinHelper.getCount() == 0 || lastText.isEmpty()) {
return false;
}
//记住最后按下拖动的时间,过短则认为是滑动,启动滑动动画
//static bool pressed = false;
static QPoint lastPos = QPoint();
static QDateTime lastTime = QDateTime::currentDateTime();
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (event->type() == QEvent::MouseButtonPress) {
} else if (event->type() == QEvent::MouseMove) {
}
} else if (watched == ui->widgetMore) {
//没有汉字或者按下的地方没有汉字或者当前汉字标签个数过少都不用继续
if (pinyinHelper.getCount() == 0 || lastText.isEmpty()) {
return false; }
//记住最后按下拖动的时间,过短则认为是滑动,启动滑动动画
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (event->type() == QEvent::MouseButtonPress) {
} else if (event->type() == QEvent::MouseButtonRelease) {
}
} else if (event->type() == QEvent::MouseMove) {
return true;
}
}
} else if (watched->inherits("QLabel")) {
//单击的是汉字标签
QLabel *lab = (QLabel *)watched;
//2022-1-7增加硬键盘模式下单击汉字标签选中
if (useHardKeyBoard && event->type() == QEvent::MouseButtonPress) {
return true;
}
if (!upper && inputType == "chinese") {
if (lab->property("labCn").toBool()) {
//记住最后按下的滚动条位置,如果滚动条一直没有变化则认为单击了标签
static int lastPosition = 0;
if (event->type() == QEvent::MouseButtonPress) {
} else if (event->type() == QEvent::MouseButtonRelease) {
if (event->type() == QEvent::MouseButtonPress) {
} else if (event->type() == QEvent::MouseButtonRelease) {
} else if (event->type() == QEvent::RequestSoftwareInputPanel) {
showPanel();
} else if (event->type() == QEvent::CloseSoftwareInputPanel) {
hidePanel();
}
}
return QWidget::eventFilter(watched, event);
}
#include eventfilter.h
#include
#include
#include
#include
EventFilter::EventFilter(QWidget *parent,Qt::WindowFlags f)
: QDialog(parent,f)
{
setWindowTitle(tr(事件过滤));
label1 = new QLabel;
Image1.load(../image/1.png);
label1->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
label1->setPixmap(QPixmap::fromImage(Image1));
label2 = new QLabel;
Image2.load(../image/2.png);
label2->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
label2->setPixmap(QPixmap::fromImage(Image2));
label3 = new QLabel;
Image3.load(../image/3.png);
label3->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
label3->setPixmap(QPixmap::fromImage(Image3));
stateLabel = new QLabel(tr(鼠标按下标志));
stateLabel->setAlignment(Qt::AlignHCenter);
QHBoxLayout *layout=new QHBoxLayout;
layout->addWidget(label1);
layout->addWidget(label2);
layout->addWidget(label3);
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addLayout(layout);
mainLayout->addWidget(stateLabel);
label1->installEventFilter(this);
label2->installEventFilter(this);
label3->installEventFilter(this);
}
EventFilter::~EventFilter()
{
}
bool EventFilter::eventFilter(QObject *watched, QEvent *event)
{
if(watched==label1)
{
if(event->type()==QEvent::MouseButtonPress)
{
QMouseEvent *mouseEvent=(QMouseEvent *)event;
if(mouseEvent->buttons()&Qt::LeftButton)
{
stateLabel->setText(tr(左键按下左边图片));
}
else if(mouseEvent->buttons()&Qt::MidButton)
{
stateLabel->setText(tr(中键按下左边图片));
}
else if(mouseEvent->buttons()&Qt::RightButton)
{
stateLabel->setText(tr(右键按下左边图片));
}
QMatrix matrix;
matrix.scale(1.8,1.8);
QImage tmpImg=Image1.transformed(matrix);
label1->setPixmap(QPixmap::fromImage(tmpImg));
}
if(event->type()==QEvent::MouseButtonRelease)
{
stateLabel->setText(tr(鼠标释放左边图片));
label1->setPixmap(QPixmap::fromImage(Image1));
}
}
else if(watched==label2)
{
if(event->type()==QEvent::MouseButtonPress)
{
QMouseEvent *mouseEvent=(QMouseEvent *)event;
if(mouseEvent->buttons()&Qt::LeftButton)
{
stateLabel->setText(tr(左键按下中间图片));
}
else if(mouseEvent->buttons()&Qt::MidButton)
{
stateLabel->setText(tr(中键按下中间图片));
}
else if(mouseEvent->buttons()&Qt::RightButton)
{
stateLabel->setText(tr(右键按下中间图片));
}
QMatrix matrix;
matrix.scale(1.8,1.8);
QImage tmpImg=Image2.transformed(matrix);
label2->setPixmap(QPixmap::fromImage(tmpImg));
}
if(event->type()==QEvent::MouseButtonRelease)
{
stateLabel->setText(tr(鼠标释放中间图片));
label2->setPixmap(QPixmap::fromImage(Image2));
}
}
else if(watched==label3)
{
if(event->type()==QEvent::MouseButtonPress)
{
QMouseEvent *mouseEvent=(QMouseEvent *)event;
if(mouseEvent->buttons()&Qt::LeftButton)
{
stateLabel->setText(tr(左键按下右边图片));
}
else if(mouseEvent->buttons()&Qt::MidButton)
{
stateLabel->setText(tr(中键按下右边图片));
}
else if(mouseEvent->buttons()&Qt::RightButton)
{
stateLabel->setText(tr(右键按下右边图片));
}
QMatrix matrix;
matrix.scale(1.8,1.8);
QImage tmpImg=Image3.transformed(matrix);
label3->setPixmap(QPixmap::fromImage(tmpImg));
}
if(event->type()==QEvent::MouseButtonRelease)
{
stateLabel->setText(tr(鼠标释放右边图片));
label3->setPixmap(QPixmap::fromImage(Image3));
}
}
return QDialog::eventFilter(watched,event);
}
SIGNAL 和 SLOT 是 Qt 的宏,用于指明信号和槽,并将它们的参数转换为相应的字符串。
connect(spinNum, SIGNAL(valueChanged(int)), this, SLOT(addFun(int));
connect(spinNum, SIGNAL(valueChanged(int)), this, SLOT(updateStatus(int));
connect(ui->rBtnBlue,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
connect(ui->rBtnRed,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
connect(ui->rBtnBlack,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
connect(spinNum, SIGNAL(valueChanged(int)), this, SIGNAL (refreshInfo(int));
严格的情况下,信号与槽的参数个数和类型需要一致,至少信号的参数不能少于槽的参数。
如果不匹配,会出现编译错误或运行错误。
在使用信号与槽的类中,必须在类的定义中加入宏 Q_OBJECT。
当一个信号被发射时,与其关联的槽函数通常被立即执行,就像正常调用一个函数一样。
只有当信号关联的所有槽函数执行完毕后,才会执行发射信号处后面的代码。
/* 设定两个QPushButton对象的位置 */
pushButton1->setGeometry(300,200,80,40);
pushButton2->setGeometry(400,200,80,40);
connect(pushButton1, SIGNAL(clicked()), this, SLOT(pushButton1_Clicked()));
connect(pushButton2, SIGNAL(clicked()), this, SLOT(pushButton2_Clicked()));
connect(sndTimer,&QTimer::timeout,={
updateQStringList();
emit edit_textChanged(getstep().toInt(),m_stlist);
});