Qt中事件(event)的接受(accept)与忽略(ignore)

之前一直对Qt的事件不甚理解,今天结合豆子哥的教程再在Vs2013+Qt 编译环境下进行编程后终于弄懂了,简单地记录一下我认为比较重要的点如下:

1.事件的传播是在组件层次上面的,而不是依靠类继承机制。
注:这句话很关键,当触发一个窗口组件时,如果ignore了,则事件会继续传播到上层组件。如下程序,点击了CustomButton按钮,则会触发CustomWidget和MainWindow这2个上级组件,同样,当点击CustomWidget组件时,将会触发MainWindow这个上级组件。
2.重写事件回调函数时,时刻注意是否需要通过调用父类的同名函数来确保原有实现仍能进行。
注:重写事件函数时,很容易出现覆盖构造函数的实现。
3.Qt中事件对象默认是 accept 的,而作为所有组件的父类QWidget的默认实现则是调用ignore()。
注:如果要忽略事件,需要调用QWidget的默认来实现,否则就等于接受了事件。

//custombutton.h
class CustomButton : public QPushButton
{
	Q_OBJECT
public:
	CustomButton(QWidget *parent) : QPushButton(parent)
	{
	}
protected:
	void mousePressEvent(QMouseEvent *event)
	{
		event->ignore();
		qDebug() << "CustomButton";
	}
};

class CustomButtonEx : public CustomButton
{
	Q_OBJECT
public:
	CustomButtonEx(QWidget *parent) : CustomButton(parent)
	{
	}
protected:
	void mousePressEvent(QMouseEvent *event)
	{
		event->ignore();
		qDebug() << "CustomButtonEx";
	}
};

class CustomWidget : public QWidget
{
	Q_OBJECT
public:
	CustomWidget(QWidget *parent) : QWidget(parent)
	{
	}
protected:
	void mousePressEvent(QMouseEvent *event)
	{
		QWidget::mousePressEvent(event);
		qDebug() << "CustomWidget";
	}
};

class MainWindow : public QMainWindow
{
	Q_OBJECT
public:
	MainWindow(QWidget *parent = 0) : QMainWindow(parent)
	{
		CustomWidget *widget = new CustomWidget(this);
		CustomButton *cbex = new CustomButton(widget);
		cbex->setText(tr("CustomButton"));
		CustomButtonEx *cb = new CustomButtonEx(widget);
		cb->setText(tr("CustomButtonEx"));

		QTextEdit *textEdit = new QTextEdit(widget);
		setCentralWidget(textEdit);
		connect(textEdit, &QTextEdit::textChanged, [=]() {
			this->setWindowModified(true);
		});

		QVBoxLayout *widgetLayout = new QVBoxLayout(widget);
		widgetLayout->addWidget(cbex);
		widgetLayout->addWidget(cb);
		widgetLayout->addWidget(textEdit);
		this->setCentralWidget(widget);

		setWindowTitle("TextPad [*]");
	}
protected:
	void mousePressEvent(QMouseEvent *event)
	{
		qDebug() << "MainWindow";
	}
	void closeEvent(QCloseEvent *event)
	{
		if (isWindowModified()) {
			bool exit = QMessageBox::question(this,
				tr("Quit"),
				tr("Are you sure to quit this application?"),
				QMessageBox::Yes | QMessageBox::No,
				QMessageBox::No) == QMessageBox::Yes;
			if (exit) {
				event->accept();
			}
			else {
				event->ignore();
			}
		}
		else {
			event->accept();
		}
	}
};
//main.cpp
int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	MainWindow m;
	m.show();
	return a.exec();
}

程序编译结果
Qt 学习之路 2

好的,这是一个关于QWidget窗口QPushButton对象的事件处理的例子: ```cpp class MyWidget : public QWidget { public: MyWidget(QWidget* parent = nullptr) : QWidget(parent) { QPushButton* button = new QPushButton("测试按钮", this); button->move(50, 50); button->show(); } protected: bool event(QEvent* e) override { if (e->type() == QEvent::MouseButtonPress) { qDebug() << "鼠标按下"; e->accept(); // 消费事件,不传递给父级 return true; } else if (e->type() == QEvent::MouseButtonRelease) { qDebug() << "鼠标释放"; e->ignore(); // 不消费事件,传递给父级 return false; } else { return QWidget::event(e); // 其他事件交给父类处理 } } }; ``` 在这个例子,我们自定义了一个QWidget的子类,重载了它的event()函数,来处理鼠标按下和释放事件。在构造函数,我们创建了一个QPushButton对象,并将它添加到窗口。如果是鼠标按下事件,我们打印一条消息,并消费事件(不传递给父级处理)。如果是鼠标释放事件,我们同样打印一条消息,但不消费事件(继续传递给父级处理)。对于其他事件,我们直接交给父类去处理。 现在我们可以在代码创建这个自定义窗口,并测试它的事件处理: ```cpp MyWidget* widget = new MyWidget; widget->show(); ``` 当我们点击窗口的按钮时,会在控制台输出"鼠标按下",当我们释放按钮时,会输出"鼠标释放"。由于我们在鼠标按下事件消费了事件,所以鼠标释放事件不会触发按钮的clicked()信号。 在这个例子,我们同样使用了accept()和ignore()函数。这两个函数通常用于处理一些特定的事件,例如QKeyEvent。当我们在重载keyPressEvent()函数时,如果我们想消费某个特定按键的事件,可以调用accept()函数,否则调用ignore()函数。这样做可以防止事件被传递给父级,或者被其他控件消费。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值