just acceptedd信号跟accept槽 在什么情况下触发

Qt 学习之路 2(19):事件的接受与忽略 | DevBean Tech World
&/&&/&Qt 学习之路 2(19):事件的接受与忽略
Qt 学习之路 2(19):事件的接受与忽略
更新有关accept()和ignore()函数的相关内容。
增加有关accept()和ignore()函数的示例。
上一章我们介绍了有关事件的相关内容。我们曾经提到,事件可以依情况接受和忽略。现在,我们就来了解下有关事件的更多的知识。
首先来看一段代码:
// ---------- custombutton.h ---------- //
class CustomButton : public QPushButton
CustomButton(QWidget *parent = 0);
void onButtonCliecked();
// ---------- custombutton.cpp ---------- //
CustomButton::CustomButton(QWidget *parent) :
QPushButton(parent)
connect(this, &CustomButton::clicked,
this, &CustomButton::onButtonCliecked);
void CustomButton::onButtonCliecked()
qDebug() && "You clicked this!";
// ---------- main.cpp ---------- //
int main(int argc, char *argv[])
QApplication a(argc, argv);
btn.setText("This is a Button!");
btn.show();
return a.exec();
1234567891011121314151617181920212223242526272829303132333435
//!!! Qt5// ---------- custombutton.h ---------- //class CustomButton : public QPushButton{&&&&Q_OBJECTpublic:&&&&CustomButton(QWidget *parent = 0);private:&&&&void onButtonCliecked();};&// ---------- custombutton.cpp ---------- //CustomButton::CustomButton(QWidget *parent) :&&&&QPushButton(parent){&&&&connect(this, &CustomButton::clicked,&&&&&&&&&&&&this, &CustomButton::onButtonCliecked);}&void CustomButton::onButtonCliecked(){&&&&qDebug() && "You clicked this!";}&// ---------- main.cpp ---------- //int main(int argc, char *argv[]){&&&&QApplication a(argc, argv);&&&&&CustomButton btn;&&&&btn.setText("This is a Button!");&&&&btn.show();&&&&&return a.exec();}
这是一段简单的代码,经过我们前面一段时间的学习,我们已经能够知道这段代码的运行结果:点击按钮,会在控制台打印出“You clicked this!”字符串。这是我们前面介绍过的内容。下面,我们向CustomButton类添加一个事件函数:
// CustomButton
protected:
void mousePressEvent(QMouseEvent *event);
// ---------- custombutton.cpp ---------- //
void CustomButton::mousePressEvent(QMouseEvent *event)
if (event-&button() == Qt::LeftButton) {
qDebug() && "left";
QPushButton::mousePressEvent(event);
1234567891011121314151617
// CustomButton...protected:&&&&void mousePressEvent(QMouseEvent *event);...&// ---------- custombutton.cpp ---------- //...void CustomButton::mousePressEvent(QMouseEvent *event){&&&&if (event-&button() == Qt::LeftButton) {&&&&&&&&qDebug() && "left";&&&&} else {&&&&&&&&QPushButton::mousePressEvent(event);&&&&}}...
我们重写了CustomButton的mousePressEvent()函数,也就是鼠标按下。在这个函数中,我们判断如果鼠标按下的是左键,则打印出来“left”字符串,否则,调用父类的同名函数。编译运行这段代码,当我们点击按钮时,“You clicked this!”字符串不再出现,只有一个“left”。也就是说,我们把父类的实现覆盖掉了。由此可以看出,父类QPushButton的mousePressEvent()函数中肯定发出了clicked()信号,否则的话,我们的槽函数怎么会不执行了呢?这暗示我们一个非常重要的细节:当重写事件回调函数时,时刻注意是否需要通过调用父类的同名函数来确保原有实现仍能进行!比如我们的CustomButton类,如果像我们这么覆盖函数,clicked()信号永远不会发生,你连接到这个信号的槽函数也就永远不会被执行。这个错误非常隐蔽,很可能会浪费你很多时间才能找到。因为这个错误不会有任何提示。这一定程度上说,我们的组件“忽略”了父类的事件,但这更多的是一种违心之举,一种错误。
通过调用父类的同名函数,我们可以把 Qt 的事件传递看成链状:如果子类没有处理这个事件,就会继续向其父类传递。Qt 的事件对象有两个函数:accept()和ignore()。正如它们的名字一样,前者用来告诉 Qt,这个类的事件处理函数想要处理这个事件;后者则告诉 Qt,这个类的事件处理函数不想要处理这个事件。在事件处理函数中,可以使用isAccepted()来查询这个事件是不是已经被接收了。具体来说:如果一个事件处理函数调用了一个事件对象的accept()函数,这个事件就不会被继续传播给其父组件;如果它调用了事件的ignore()函数,Qt 会从其父组件中寻找另外的接受者。
事实上,我们很少会使用accept()和ignore()函数,而是像上面的示例一样,如果希望忽略事件(所谓忽略,是指自己不想要这个事件),只要调用父类的响应函数即可。记得我们曾经说过,Qt 中的事件都是 protected 的,因此,重写的函数必定存在着其父类中的响应函数,所以,这个方法是可行的。为什么要这么做,而不是自己去手动调用这两个函数呢?因为我们无法确认父类中的这个处理函数有没有额外的操作。如果我们在子类中直接忽略事件,Qt 会去寻找其他的接收者,该子类的父类的操作会被忽略(因为没有调用父类的同名函数),这可能会有潜在的危险。为了避免自己去调用accept()和ignore()函数,而是尽量调用父类实现,Qt 做了特殊的设计:事件对象默认是 accept 的,而作为所有组件的父类QWidget的默认实现则是调用ignore()。这么一来,如果你自己实现事件处理函数,不调用QWidget的默认实现,你就等于是接受了事件;如果你要忽略事件,只需调用QWidget的默认实现。这一点我们前面已经说明。下面可以从代码级别来理解这一点,我们可以查看一下QWidget的mousePressEvent()函数的实现:
void QWidget::mousePressEvent(QMouseEvent *event)
event-&ignore();
if ((windowType() == Qt::Popup)) {
event-&accept();
while ((w = QApplication::activePopupWidget()) && w != this){
w-&close();
if (QApplication::activePopupWidget() == w)
w-&hide(); // hide at least
if (!rect().contains(event-&pos())){
1234567891011121314151617
//!!! Qt5void QWidget::mousePressEvent(QMouseEvent *event){&&&&event-&ignore();&&&&if ((windowType() == Qt::Popup)) {&&&&&&&&event-&accept();&&&&&&&&QWidget* w;&&&&&&&&while ((w = QApplication::activePopupWidget()) && w != this){&&&&&&&&&&&&w-&close();&&&&&&&&&&&&if (QApplication::activePopupWidget() == w)&&&&&&&&&&&&&&&&w-&hide(); // hide at least&&&&&&&&}&&&&&&&&if (!rect().contains(event-&pos())){&&&&&&&&&&&&close();&&&&&&&&}&&&&}}
这段代码在 Qt4 和 Qt5 中基本一致(区别在于activePopupWidget()一行,Qt4 的版本是qApp-&activePopupWidget())。注意函数的第一个语句:event-&ignore(),如果子类都没有重写这个函数,Qt 会默认忽略这个事件,继续寻找下一个事件接收者。如果我们在子类的mousePressEvent()函数中直接调用了accept()或者ignore(),而没有调用父类的同名函数,QWidget::mousePressEvent()函数中关于Popup判断的那段代码就不会被执行,因此可能会出现默认其妙的怪异现象。
针对accept()和ignore(),我们再来看一个例子:
class CustomButton : public QPushButton
CustomButton(QWidget *parent) : QPushButton(parent)
protected:
void mousePressEvent(QMouseEvent *event)
qDebug() && "CustomButton";
class CustomButtonEx : public CustomButton
CustomButtonEx(QWidget *parent) : CustomButton(parent)
protected:
void mousePressEvent(QMouseEvent *event)
qDebug() && "CustomButtonEx";
class CustomWidget : public QWidget
CustomWidget(QWidget *parent) : QWidget(parent)
protected:
void mousePressEvent(QMouseEvent *event)
qDebug() && "CustomWidget";
class MainWindow : public QMainWindow
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"));
QVBoxLayout *widgetLayout = new QVBoxLayout(widget);
widgetLayout-&addWidget(cbex);
widgetLayout-&addWidget(cb);
this-&setCentralWidget(widget);
protected:
void mousePressEvent(QMouseEvent *event)
qDebug() && "MainWindow";
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
class CustomButton : public QPushButton{&&&&Q_OBJECTpublic:&&&&CustomButton(QWidget *parent) : QPushButton(parent)&&&&{&&&&}protected:&&&&void mousePressEvent(QMouseEvent *event)&&&&{&&&&&&&&qDebug() && "CustomButton";&&&&}};&class CustomButtonEx : public CustomButton{&&&&Q_OBJECTpublic:&&&&CustomButtonEx(QWidget *parent) : CustomButton(parent)&&&&{&&&&}protected:&&&&void mousePressEvent(QMouseEvent *event)&&&&{&&&&&&&&qDebug() && "CustomButtonEx";&&&&}};&class CustomWidget : public QWidget{&&&&Q_OBJECTpublic:&&&&CustomWidget(QWidget *parent) : QWidget(parent)&&&&{&&&&}protected:&&&&void mousePressEvent(QMouseEvent *event)&&&&{&&&&&&&&qDebug() && "CustomWidget";&&&&}};&class MainWindow : public QMainWindow{&&&&Q_OBJECTpublic:&&&&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"));&&&&&&&&QVBoxLayout *widgetLayout = new QVBoxLayout(widget);&&&&&&&&widgetLayout-&addWidget(cbex);&&&&&&&&widgetLayout-&addWidget(cb);&&&&&&&&this-&setCentralWidget(widget);&&&&}protected:&&&&void mousePressEvent(QMouseEvent *event)&&&&{&&&&&&&&qDebug() && "MainWindow";&&&&}};
这段代码在一个MainWindow中添加了一个CustomWidget,里面有两个按钮对象:CustomButton和CustomButtonEx。每一个类都重写了mousePressEvent()函数。运行程序点击 CustomButtonEx,结果是
CustomButtonEx
CustomButtonEx
这是因为我们重写了鼠标按下的事件,但是并没有调用父类函数或者显式设置accept()或ignore()。下面我们在CustomButtonEx的mousePressEvent()第一行增加一句event->accept(),重新运行,发现结果不变。正如我们前面所说,QEvent默认是accept的,调用这个函数并没有什么区别。然后我们将CustomButtonEx的event->accept()改成event->ignore()。这次运行结果是
CustomButtonEx
CustomWidget
CustomButtonExCustomWidget
ignore()说明我们想让事件继续传播,于是CustomButtonEx的父组件CustomWidget也收到了这个事件,所以输出了自己的结果。同理,CustomWidget又没有调用父类函数或者显式设置accept()或ignore(),所以事件传播就此打住。这里值得注意的是,CustomButtonEx的事件传播给了父组件CustomWidget,而不是它的父类CustomButton。事件的传播是在组件层次上面的,而不是依靠类继承机制。
接下来我们继续测试,在CustomWidget的mousePressEvent()中增加QWidget::mousePressEvent(event)。这次的输出是
CustomButtonEx
CustomWidget
MainWindow
CustomButtonExCustomWidgetMainWindow
如果你把QWidget::mousePressEvent(event)改成event->ignore(),结果也是一样的。这正如我们前面说的,QWidget的默认是调用event->ignore()。
在一个特殊的情形下,我们必须使用accept()和ignore()函数,那就是窗口关闭的事件。对于窗口关闭QCloseEvent事件,调用accept()意味着 Qt 会停止事件的传播,窗口关闭;调用ignore()则意味着事件继续传播,即阻止窗口关闭。回到我们前面写的简单的文本编辑器。我们在构造函数中添加如下代码:
textEdit = new QTextEdit(this);
setCentralWidget(textEdit);
connect(textEdit, &QTextEdit::textChanged, [=]() {
this-&setWindowModified(true);
setWindowTitle("TextPad [*]");
void MainWindow::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::Y
if (exit) {
event-&accept();
event-&ignore();
event-&accept();
12345678910111213141516171819202122232425262728
//!!! Qt5...textEdit = new QTextEdit(this);setCentralWidget(textEdit);connect(textEdit, &QTextEdit::textChanged, [=]() {&&&&this-&setWindowModified(true);});&setWindowTitle("TextPad [*]");...&void MainWindow::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();&&&&}}
setWindowTitle()函数可以使用 [] 这种语法来表明,在窗口内容发生改变时(通过setWindowModified(true)函数通知),Qt 会自动在标题上面的 [] 位置替换成 * 号。我们使用 Lambda 表达式连接QTextEdit::textChanged()信号,将windowModified设置为 true。然后我们需要重写closeEvent()函数。在这个函数中,我们首先判断是不是有过修改,如果有,则弹出询问框,问一下是否要退出。如果用户点击了“Yes”,则接受关闭事件,这个事件所在的操作就是关闭窗口。因此,一旦接受事件,窗口就会被关闭;否则窗口继续保留。当然,如果窗口内容没有被修改,则直接接受事件,关闭窗口。【跟谁学社区】-学习论坛_学习小组_兴趣小组
话题小组123帮你解决孩子教育和妈妈成长问题NEW「职说Talk」,专属职场人学习的平台。NEW领先的高考状元培养社群。NEW外教爸爸双语宝宝让0-12岁儿童爱上英语三岁看小,七岁看老,家庭教育至关重要!这里有你想要的咨询,快来加入吧!嗨!We are 伐木累!一起打造嗨皮高中生活~~来找到与你相知的那一群人!情调的生活,钱多多的职场,都是我们的!张开梦想的翅膀,我们飞向新世界!粉丝互动、建议反馈,嗨起来~中国爱乐乐团第一小提琴手高中小海量资料,坚持看一年,英语会改变30年成就3000万人魅力表达、身心富足瑜伽,让你遇到最美丽的自己!解析高考招生政策,介绍大学和专业最简单方法。分数+ 能力,语言+ 逻辑。三分长相 七分打扮 会打扮的女人最好命!既然选择远方,便只顾风雨兼程关于日语、关于日本,一起聊聊吧每天都离法国更近一点在喧嚣的世界中打造一片心灵的净土!爱美术,爱生活每日变换自己的装束,分享你的美!蹦沙卡拉卡~帅哥美女看这里~大千世界,总有你不知道的事~热门帖子17278163222142612021102210341340001011110411000021010111...hi,欢迎来到跟谁学社区登录
关注我们官方微信关于跟谁学服务支持帮助中心模式对话框和非模式对话框之exec()/accept()
作为一名嵌入式工程师来说,我做的一般都是特别老土的命令行模式的软件,所以,对 对话框的模式和非模式的概念是非常不理解的。之所以会接触到这个概念,是因为我在研究QT的exec()这个货到底是个啥?结果引出了这些概念,写个总结吧。
本篇,会重点讲述模式对话框,以及exec()的用法,accept()和accepted的概念。
一.非模式对话框
return a.exec();
。按照之前对模式对话框的讲述,my1.exec()的意思就是,显示子窗口,并在这里阻塞住,知道该窗口被关闭之后,才继续往下运行!
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!当前位置:
&Completed Accept和 Accept代表什么意思?
Completed Accept和 Accept代表什么意思?
作者 andersonlyw
投过一个Elsevier的杂志,每次都是先Accept,过二天后状态变成Complete Accept。
请问这是什么意思,各代表什么?
祝大家生活愉快,科研顺利!Complete Accept:接收完成:Accept:收到
引用回帖:: Originally posted by 管天道道 at
祝大家生活愉快,科研顺利!Complete Accept:接收完成:Accept:收到 这位仁兄不要胡说啊。,Accept也是录用的意思,
从字面上理解,都是录用的意思。有何区别吗?
complete accept表示编辑的工作已经完成,现在转交到production.
accept,貌似是被录用了吧
Accept 是AE发出decision letter
时产生的状态,completed accept是editorial office 归档后产生的状态。
一般的论文最后都有一个结果,最终结果!
24小时热帖
下载小木虫APP
与700万科研达人随时交流博客访问: 959783
博文数量: 177
博客积分: 3640
博客等级: 中校
技术积分: 1768
注册时间:
分类: LINUX 22:00:25
13.2.5& accept函数处于监听状态的服务器在获得客户机的连接请求后,会将其放置在等待队列中。当系统空闲时,将接受客户机的连接请求。接收客户机的连接请求使用accept函数,该函数的具体信息如表13.6所示。表13.6& &accept函数头文件函数形式int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);说明:accept函数用于面向连接类型的套接字类型(SOCK_STREAM和SOCK_SEQPACKET)。accept函数将从连接请求队列中获得连接信息,创建新的套接字,并返回该套接字的文件描述符。新创建的套接字用于服务器与客户机的通信,而原来的套接字仍然处于监听状态。accept函数的sockfd参数为监听的套接字描述符。addr参数为指向结构体sockaddr的指针。参数addrlen为addr参数指向的内存空间的长度。错误信息:EAGAIN:套接字处于非阻塞状态,当前没有连接请求。EBADF:非法的文件描述符。ECONNABORTED:连接中断。EINTR:系统调用被信号中断。EINVAL:套接字没有处于监听状态,或非法的addrlen参数。EMFILE:达到进程打开文件描述符限制。ENFILE:达到打开文件数限制。ENOTSOCK:文件描述符为文件的文件描述符。EOPNOTSUPP:套接字类型不是SOCK_STREAM。
阅读(19062) | 评论(0) | 转发(6) |
给主人留下些什么吧!~~
请登录后评论。}

我要回帖

更多关于 license not accepted 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信