之前一直对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();
}