Qt6.0开发 第六章 事件处理
第六章 事件处理
Qt的事件系统
事件的产生与派发
GUI应用程序是由事件(event)驱动的,点击鼠标、按下某个按键、改变窗口大小等都会产生对应事件.Qt为事件处理编程提供了完善的支持.QWidget定义了大量与事件处理相关的数据类型与接口函数.
事件表示应用程序中发生的操作或变化.在Qt中,事件是对象,是QEvent类或其派生类的实例.
按事件的来源,可以将事件划分为3类:
- 自生事件(spontaneous event):是由窗口系统产生的事件.自生事件会进入系统队列,然后被应用程序的事件循环逐个处理.
- 发布事件(posted event):是由Qt或应用程序产生的事件.发布事件会进入Qt事件队列,然后由应用程序的事件循环进行处理.
- 发送事件(sent event):是由Qt或应用程序定向发送给某个对象的事件.
窗口系统产生的自生事件自动进入系统队列,应用程序发布事件进入Qt事件队列.
自生事件和发布事件的处理是异步的,也就是事件进入队列后由系统去处理,程序不会在产生事件的地方停止进行等待.
应用程序里的事件循环只处理自生事件和发布事件,而不会处理发送事件,因为发送事件由应用程序直接派发给某个对象,是以同步模式运行的.
处理事件相关的函数有:
- void QCoreApplication::postEvent(QObject *receiver,QEvent *event,int priority=Qt::NormalEventPriority)
//发布某个事件 - bool QCoreApplication::sentEvent(QObject *receiver,QEvent *event)//向某个对象发送事件
- void QCoreApplication::processEvent(QEventLoop::ProcessEventsFlags flags=QEventLoop::AllEvents)
//将事件队列里未处理的时间派发出来 - void QCoreApplication::sendPostedEvents(QObject *receiver=nullptr,int event_type=0)
//立刻将发布事件派发出去
枚举类型QEventLoop::ProcessEventsFlag有以下几种枚举值:
- QEventLoop::AllEvents:处理所有事件
- QEventLoop::ExcludeUserInputEvents::排除用户输入事件
- QEventLoop::ExcludeSocketNotifiers:排除网络socket的通知事件
- QEventLoop::WaitForMoreEvents::如果没有未处理的事件,等待更多事件
事件类和事件类型
事件是QEvent类或其派生类的实例,大多数的事件有其专门的类.QEvent是所有事件类的基类,但它不是一个抽象类,它也可以用于创建事件.
QEvent的主要接口函数有:
- void accept()//接受事件
- void ignore()//忽略事件
- bool isAccepted()//是否接受事件
- bool isInputEvent()//事件对象是否为QInputEvent或其派生类
- bool isPointerEvent()//事件对象是否为QPointerEvent或其派生类
- bool isSinglePointEvent()//事件对象是不是QSinglePointEvent或其派生类
- bool spontaneous()//是否为自生事件
- QEvent::Type type()//事件类型
常见的事件类及其所述的事件类见下表:
事件类 | 事件类型 | 事件描述 |
---|---|---|
QMouseEvent | QEvent::MouseButtonDblClick QEvent::MouseButtonPress QEvent::MouseButtonRelease QEvent::MouseMove |
鼠标双击 鼠标按键按下 鼠标按键释放 鼠标移动 |
QWheelEvent | QEvent::QWheelEvent | 鼠标滚轮滚动 |
QHoverEvent | QEvent::HoverEnter QEvent::HoverLeave QEvent::HoverMove |
鼠标光标移动到组件上方并悬停 鼠标光标离开某个组件上方 鼠标光标在组件上方移动 |
QEnterEvent | QEvent::Enter | 鼠标光标进入组件或窗口边界范围内 |
QEvent | QEvent::Leave | 鼠标光标离开组件或窗口边界范围 |
QKeyEvent | QEvent::KeyPress QEvent::KeyRelease |
键盘按键按下 键盘按键释放 |
QFocusEvent | QEvent::FocusIn QEvent::FocusOut QEvent::FocusAboutToChange |
组件或窗口获得键盘的输入焦点 组件或窗口失去键盘的输入焦点 组件或窗口的键盘输入焦点即将变化 |
QShowEvent | QEvent::Show | 窗口在屏幕上显示出来,或组件变得可见 |
QHideEvent | QEvent::Hide | 窗口在屏幕上隐藏,或组件变得不可见 |
QMoveEvent | QEvent::Mode | 组件或窗口的位置移动 |
QCloseEvent | QEvent::Close | 窗口或组件被关闭 |
QPaintEvent | QEvent::Paint | 界面组件需要更新重绘 |
QResizeEvent | QEvent::Resize | 窗口或组件改变大小 |
QStatusTipEvent | QEvent::StatusTip | 请求显示组件的statusTip信息 |
QHelpEvent | QEvent::ToolTip QEvent::WhatsThis |
请求显示组件的toolTip信息 请求显示组件的whatsThis信息 |
QDragEnterEvent | QEvent::DragEvent | 在拖放操作中,鼠标光标移动到组件上方 |
QDragLeaveEvent | QEvent::DragLeave | 在拖放操作中,鼠标光标离开了组件 |
QDragMoveEvent | QEvent::DragMove | 拖放操作正在移动过程中 |
QDropEvent | QEvent::Drop | 拖放操作完成,即放下拖动的对象 |
QTouchEvent | QEvent::TouchBegin QEvent::TouchCancel QEvent::TouchEnd QEvent::TouchUpdate |
开始一个触屏事件序列 取消一个触屏事件序列 结束一个触屏事件序列 触屏事件 |
QGestureEvent | QEvent::Gesture | 手势事件 |
QNativeGestureEvent | QEvent::NativeGesture | 手势事件 |
QActionEvent | QEvent::ActionAdded QEvent::ActionChanged QEvent::ActionRemoved |
运行QWidget::addAction()函数 Action改变时触发 Action移除时触发的事件 |
事件的处理
任何从QObject派生的类都可以处理事件,但其中主要是从QWidget派生的窗口类和界面组件类需要处理事件.
一个对象接收到应用程序派发来的事件后,首先会由函数event()处理.event()是QObject类中定义的一个虚函数,其函数原型定义如下:
- bool QObject::event(QEvent* e)
被accept()接受的事件由事件接收者处理,被ignore()忽略的事件则传播到事件接收者的父容器组件.这称为事件的传播(propagation),事件最后可能会传播给窗口.
QWidget类中定义了很多典型事件的处理函数,这些函数都有一个参数event,它是具体事件类的对象.一个函数对应一个类型的事件,但是多个函数的参数event的类型可能是一样的.
事件处理函数名 | 对应的事件类型 | 参数event的类型 | 事件描述 |
---|---|---|---|
mouseDoubleClickEvent() | QEvent::MouseButtonDblClick | QMouseEvent | 鼠标双击 |
mousePressEvent() | QEvent::MouseButtonPress | QMouseEvent | 鼠标按键按下 |
mouseReleaseEvent() | QEvent::MouseButtonRelease | QMouseEvent | 鼠标按键释放 |
mouseMoveEvent() | QEvent::MouseMove | QMouseEvent | 鼠标移动 |
wheelEvent() | QEvent::QWheelEvent | QWheelEvent | 鼠标滚轮滚动 |
enterEvent() | QEvent::Enter | QEnterEvent | 鼠标光标进入组件或窗口边界范围内 |
leaveEvent() | QEvent::Leave | QEvent | 鼠标光标离开组件或窗口边界范围 |
keyPressEvent() | QEvent::KeyPress | QKeyEvent | 键盘按键按下 |
keyReleaseEvent() | QEvent::KeyRelease | QKeyEvent | 键盘按键释放 |
focusInEvent() | QEvent::FocusIn | QFocusEvent | 组件或窗口获得键盘的输入焦点 |
focusOutEvent() | QEvent::FoucusOut | QFocusEvent | 组件或窗口失去键盘的输入焦点 |
showEvent() | QEvent::Show | QShowEvent | 窗口在屏幕上显示出来 |
hideEvent() | QEvent::Hide | QHideEvent | 窗口在屏幕上隐藏 |
moveEvent() | QEvent::Move | QMoveEvent | 组件或窗口的位置移动 |
closeEvent() | QEvent::Close | QCloseEvent | 窗口或组件被关闭 |
paintEvent() | QEvent::Paint | QPaintEvent | 界面组件需要重绘 |
resizeEvent() | QEvent::Resize | QResizeEvent | 窗口或组件需要改变大小 |
dragEnterEvent() | QEvent::DragEvent | QDragEnterEvent | 在拖放操作中,鼠标光标移动到组件上方 |
dragLeaveEvent() | QEvent::DragLeave | QDragLeaveEvent | 在拖放操作中,鼠标光标离开了组件 |
dragMoveEvent() | QEvent::DragMove | QDragMoveEvent | 拖放操作正在移动过程中 |
dropEvent() | QEvent::Drop | QDropEvent | 拖放操作完毕,即放下拖动的对象 |
事件与信号
事件和信号的区别在于,事件通常是由窗口系统或应用程序产生的,信号则是Qt定义或用户自定义的.
在使用界面组件为交互操作编程的时候,我们通常选择合适的信号,为该信号编写槽函数.
但是,Qt的界面只将少数事件封装成了信号,对于某些事件可能缺少对应的信号.在这种情况,我们可以从某些类继承定义出一个新类,通过自定义信号与事件处理来达到新事件的效果.
应用程序派发给界面组件的事件首先会由其函数event()处理,因而通过重载event()可以实现对事件处理机制的自定义化.
下面是一个综合应用的实例:
tmy_label.h
#ifndef TMYLABEL_H
#define TMYLABEL_H
#include <QLabel>
#include <QObject>
#include <QEvent>
class TMyLabel : public QLabel
{
Q_OBJECT
public:
TMyLabel(QWidget *parent=nullptr);
signals:
void doubleClicked();
// QWidget interface
protected:
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
// QObject interface
public:
virtual bool event(QEvent *event) override;
};
#endif // TMYLABEL_H
mainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
// QWidget interface
private slots:
void do_doubleClick();
protected:
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
};
#endif // MAINWINDOW_H
tmy_label.cpp
#include "tmy_label.h"
TMyLabel::TMyLabel(QWidget *parent)
:QLabel(parent)
{
setAttribute(Qt::WA_Hover,true);
}
void TMyLabel::mouseDoubleClickEvent(QMouseEvent *event)
{
Q_UNUSED(event);
emit doubleClicked();
}
bool TMyLabel::event(QEvent *event)
{
if(event->type()==QEvent::HoverEnter){
QPalette plet=this->palette();
plet.setColor(QPalette::WindowText,Qt::red);
setPalette(plet);
}
else if(event->type()==QEvent::HoverLeave){
QPalette plet=this->palette();
plet.setColor(QPalette::WindowText,Qt::black);
setPalette(plet);
}
return QLabel::event(event);
}
mainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->label,SIGNAL(doubleClicked()),this,SLOT(do_doubleClick()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::do_doubleClick()
{
ui->label->setText("标签被双击,信号槽得到响应");
ui->label->adjustSize();
}
void MainWindow::mouseDoubleClickEvent(QMouseEvent *event)
{
Q_UNUSED(event);
ui->label->setText("被双击力(悲)");
ui->label->adjustSize();
}
事件过滤器
从上面给出的例子可以看到,一个界面组件如果要对事件进行处理,需要从父类继承定义一个新类,在新类里编写程序直接处理事件,或者将事件转换为信号.
如果不想定义一个新的类,可以用事件过滤器(event filter)对界面组件的事件进行处理.
事件过滤器是QObject提供的一种处理事件的方法,它可以将一个对象的事件委托给另一个对象来监视并处理.
要实现事件过滤器功能,需要完成两项操作:
- 被监视对象使用函数installEventFilter()将自己注册给监视对象,监视对象就是过滤器.
- 监视对象重新实现函数eventFilter()将监视到的事件进行处理.
涉及到的函数原型有:
- void QObject::installEventFilter(QObject *filterObj)
- bool QObject::eventFilter(QObject *watched,QEvent *event)
下面是一个例子:
mainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->lbUp->installEventFilter(this);
ui->lbDown->installEventFilter(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
if(watched==ui->lbUp)
if(event->type()==QEvent::Enter)
ui->lbUp->setStyleSheet("background-color:rgb(170,255,255);");
else if(event->type()==QEvent::Leave){
ui->lbUp->setText("单击我");
ui->lbUp->setStyleSheet("");
}
else if(event->type()==QEvent::MouseButtonPress)
ui->lbUp->setText("Button Pressed");
else if(event->type()==QEvent::MouseButtonRelease)
ui->lbUp->setText("Button Release");
if(watched==ui->lbDown)
if(event->type()==QEvent::Enter)
ui->lbDown->setStyleSheet("background-color:rgb(85,255,127);");
else if(event->type()==QEvent::Leave){
ui->lbDown->setText("双击我");
ui->lbDown->setStyleSheet("");
}
else if(event->type()==QEvent::MouseButtonDblClick)
ui->lbDown->setText("Button Double Clicked");
return QWidget::eventFilter(watched,event);
}
拖放事件与拖放操作
拖放(drag and drop)操作是GUI应用程序中经常使用的一种操作.
拖放由两个操作组成:拖动(drag)和放置(drop).被拖动的组件称为拖动点(drag site).接收拖动操作的组件称为放置点(drop site).
拖动点与放置点可以是不同的组件.甚至可以是不同的应用程序.
整个拖放操作可以分解为两个过程:
- 拖动点启动拖动操作:被拖动组件通过mousePressEvent()和mouseMoveEvent()这两个事件处理函数的处理,检测到左键按下并移动时就可以启动拖动操作.
- 放置点处理放置操作:当拖动操作移动到放置点范围内时,首先触发dragEnterEvent()事件处理函数,在此函数里一般要通过QDrag对象的mimeData数据判断拖动操作的来源和参数,以决定是否触发dropEvent()接收此拖动操作.
下面是两个相关函数的原型: - void dragEnterEvent(QDragEnterEvent *event);
- void dropEvent(QDropEvent *event);
还有一些相关的函数包括有:
- acceptDrops():返回一个bool型值,表示组件是否可以作为放置点接受放置操作
- dragEnabled():返回一个bool型值,表示组件是否可以作为拖动点启动拖动操作
- dragDropMode():返回结果为QAbstractItemView类型的值,表示拖放操作模式
- defaultDropAction():返回结果为枚举类型Qt::DropAction.当组件作为放置点时,它表示完成拖放操作时数据操作的模式.
以上函数都有其对应的setter函数.
QAbstractItemView::DragDropMode的枚举值:
- QAbstractItemView::NoDragDrop//组件不支持拖放操作
- QAbstractItemView::DragOnly//组件只支持拖动操作
- QAbstractItemView::DropOnly//组件只支持放置操作
- QAbstractItemView::DragDrop//组件支持拖放操作
- QAbstractItemView::InternalMove//组件支持内部项拖放操作
Qt::DropAction的枚举值:
- Qt::CopyAction//将数据复制到放置点处
- Qt::MoveAction//将数据从拖动点组件移动到放置点处
- Qt::LinkAction//在拖动点组件和放置点组件之间建立数据连接
- Qt::IgnoreAction//对数据不进行任何操作
QWidget类有一个属性acceptDrops,如果设置为true,那么对应的这个组件就可以设置为一个放置点.
QAbstractItemView类定义了更多与拖动操作相关的函数,因而其相关类可以作为放置点.
多用途互联网跟邮件扩展(multipurpose Internet mail extensions,MIME)被设计的最初目的是在发送电子邮件时附加多媒体数据,使邮件客户端能根据其类型进行处理.
QMimeData是对MIME数据的封装,在拖放操作和剪切板操作中都用QMimeData描述传输的数据.
MIME格式 | 判断函数 | 获取数据的函数 | 设置函数 |
---|---|---|---|
text/plain | hasText() | text() | setText() |
text/html | hasHtml() | html() | setHtml() |
text/url-list | hasUrls() | urls() | setUrls() |
image/* | hasImage() | imageData() | setImageData() |
application/x-color | hasColor() | colorData() | setColorData() |
下面是一个综合使用的例子:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
setAcceptDrops(true);
ui->plainTextEdit->setAcceptDrops(false);
ui->plainTextEdit->setAcceptDrops(false);
ui->label->setScaledContents(true);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::resizeEvent(QResizeEvent *event)
{
QSize sz=ui->plainTextEdit->size();
ui->plainTextEdit->move(0,5);
ui->label->move(0,sz.height()+10);
ui->plainTextEdit->resize(this->width(),sz.height());
ui->label->resize(this->width(),this->height()-sz.height());
event->accept();
}
void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
ui->plainTextEdit->clear();
ui->plainTextEdit->appendPlainText(QString("dragEnter事件:mimeData的Format"));
for(auto &iter:event->mimeData()->formats())
ui->plainTextEdit->appendPlainText(iter);
ui->plainTextEdit->appendPlainText(QString("dragEnter事件:mimeData的Urls"));
for(auto &iter:event->mimeData()->urls())
ui->plainTextEdit->appendPlainText(iter.path());
if(event->mimeData()->hasUrls()){
QString filename=event->mimeData()->urls().at(0).fileName();
QFileInfo fileInfo(filename);
QString ex=fileInfo.suffix().toUpper();
if(ex=="JPG")
event->acceptProposedAction();
else
event->ignore();
}
else
event->ignore();
}
void MainWindow::dropEvent(QDropEvent *event)
{
QString filepath=event->mimeData()->urls().at(0).path();
filepath=filepath.right(filepath.length()-1);
QPixmap pixmap(filepath);
ui->label->setPixmap(pixmap);
event->accept();
}
Qt类库中的一些类实现了完整的拖放操作功能,例如QAbstractItemView等.这些类都有一个函数setDragEnabled,当设置为true时,组件就可以作为一个拖动点,具有默认的拖动操作.
下面是一个综合应用拖放的例子:
mainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGroupBox>
#include <QAbstractItemView>
#include <QLabel>
#include <QEvent>
#include <QKeyEvent>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_radListSource_clicked();
void on_radListWidget_clicked();
void on_radTreeWidget_clicked();
void on_radTableWidget_clicked();
void on_chkAcceptDrops_clicked(bool checked);
void on_chkDragEnabled_clicked(bool checked);
void on_comMode_currentIndexChanged(int index);
void on_comAction_currentIndexChanged(int index);
private:
Ui::MainWindow *ui;
QAbstractItemView *m_itemView=nullptr;
void refreshToUI(QLabel *curGroupBox);
int getDropActionIndex(Qt::DropAction actionType);
Qt::DropAction getDropActionType(int index);
// QObject interface
public:
virtual bool eventFilter(QObject *watched, QEvent *event) override;
};
#endif // MAINWINDOW_H
mainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_itemView=ui->listSource;
ui->listSource->setAcceptDrops(true);
ui->listSource->setDefaultDropAction(Qt::CopyAction);
ui->listSource->setDragDropMode(QAbstractItemView::DragDrop);
ui->listSource->setDragEnabled(true);
ui->listWidget->setAcceptDrops(true);
ui->listWidget->setDefaultDropAction(Qt::CopyAction);
ui->listWidget->setDragDropMode(QAbstractItemView::DragDrop);
ui->listWidget->setDragEnabled(true);
ui->treeWidget->setAcceptDrops(true);
ui->treeWidget->setDefaultDropAction(Qt::CopyAction);
ui->treeWidget->setDragDropMode(QAbstractItemView::DragDrop);
ui->treeWidget->setDragEnabled(true);
ui->treeWidget->clear();
ui->tableWidget->setAcceptDrops(true);
ui->tableWidget->setDefaultDropAction(Qt::MoveAction);
ui->tableWidget->setDragDropMode(QAbstractItemView::DragDrop);
ui->tableWidget->setDragEnabled(true);
ui->listSource->installEventFilter(this);
ui->listWidget->installEventFilter(this);
ui->treeWidget->installEventFilter(this);
ui->tableWidget->installEventFilter(this);
refreshToUI(ui->lbListSource);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::refreshToUI(QLabel *curGroupBox)
{
ui->chkAcceptDrops->setChecked(m_itemView->acceptDrops());
ui->chkDragEnabled->setChecked(m_itemView->dragEnabled());
ui->comMode->setCurrentIndex((int)m_itemView->dragDropMode());
int index=getDropActionIndex(m_itemView->defaultDropAction());
ui->comAction->setCurrentIndex(index);
QFont font=curGroupBox->font();
font.setBold(false);
ui->lbListSource->setFont(font);
ui->lbListWidget->setFont(font);
ui->lbTreeWidget->setFont(font);
ui->lbTableWidget->setFont(font);
font.setBold(true);
curGroupBox->setFont(font);
}
int MainWindow::getDropActionIndex(Qt::DropAction actionType)
{
switch(actionType){
case Qt::CopyAction:
return 0;
case Qt::MoveAction:
return 1;
case Qt::LinkAction:
return 2;
case Qt::IgnoreAction:
return 3;
default:
return 0;
}
}
Qt::DropAction MainWindow::getDropActionType(int index)
{
switch(index){
case 0:
return Qt::CopyAction;
case 1:
return Qt::MoveAction;
case 2:
return Qt::LinkAction;
case 3:
return Qt::IgnoreAction;
default:
return Qt::CopyAction;
}
}
void MainWindow::on_radListSource_clicked()
{
m_itemView=ui->listSource;
refreshToUI(ui->lbListSource);
}
void MainWindow::on_radListWidget_clicked()
{
m_itemView=ui->listWidget;
refreshToUI(ui->lbListWidget);
}
void MainWindow::on_radTreeWidget_clicked()
{
m_itemView=ui->treeWidget;
refreshToUI(ui->lbTreeWidget);
}
void MainWindow::on_radTableWidget_clicked()
{
m_itemView=ui->tableWidget;
refreshToUI(ui->lbTableWidget);
}
void MainWindow::on_chkAcceptDrops_clicked(bool checked)
{
m_itemView->setAcceptDrops(checked);
}
void MainWindow::on_chkDragEnabled_clicked(bool checked)
{
m_itemView->setDragEnabled(checked);
}
void MainWindow::on_comMode_currentIndexChanged(int index)
{
m_itemView->setDragDropMode((QAbstractItemView::DragDropMode)index);
}
void MainWindow::on_comAction_currentIndexChanged(int index)
{
m_itemView->setDefaultDropAction(getDropActionType(index));
}
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
if(event->type()!=QEvent::KeyPress)
return QWidget::eventFilter(watched,event);
QKeyEvent *keyEvent=static_cast<QKeyEvent*>(event);
if(keyEvent->key()!=Qt::Key_Delete)
return QWidget::eventFilter(watched,event);
if(watched==ui->listSource)
delete ui->listSource->takeItem(ui->listSource->currentRow());
else if(watched==ui->listWidget)
delete ui->listWidget->takeItem(ui->listWidget->currentRow());
else if(watched==ui->treeWidget){
QTreeWidgetItem *curItem=ui->treeWidget->currentItem();
if(curItem->parent()!=nullptr)
curItem->parent()->removeChild(curItem);
else{
int index=ui->treeWidget->indexOfTopLevelItem(curItem);
ui->treeWidget->takeTopLevelItem(index);
}
delete curItem;
}
else if(watched==ui->tableWidget)
delete ui->tableWidget->takeItem(ui->tableWidget->currentRow(),ui->tableWidget->currentColumn());
return true;
}