Qt 实现动态调整流程指令顺序(通过鼠标事件实现)
// 事件 bool CTestCfgWidget::eventFilter(QObject *, QEvent *evt) { //获取鼠标坐标和窗口坐标 static QPoint lastPnt; static bool isHover = false; static bool ismove = false; // 鼠标按下 if (evt->type() == QEvent::MouseButtonPress) { QMouseEvent* e = static_cast<QMouseEvent*>(evt); //得到水平布局的数量,循环判断鼠标在一个水平布局中 int layoutcount = m_processcfg_mainlayout->count(); for (int k=0;k<layoutcount;k++) { QHBoxLayout *hlayout = static_cast<QHBoxLayout *>(m_processcfg_mainlayout->itemAt(k)); if (!hlayout) { return true; } QRect rect = hlayout->geometry(); //is the mouse is clicking the key and //if the mouse click the right key if (rect.contains(e->pos()) && (e->button() == Qt::LeftButton)) { lastPnt = e->pos(); isHover = true; //得到要移动的layout编号 m_layoutno = k; break; } } } // 鼠标移动 else if (evt->type() == QEvent::MouseMove && isHover) { ismove = true; // 鼠标位置 QMouseEvent* e = static_cast<QMouseEvent*>(evt); int dx = e->pos().x() - lastPnt.x(); int dy = e->pos().y() - lastPnt.y(); lastPnt = e->pos(); // 修改对象位置 m_label[m_layoutno]->move(m_label[m_layoutno]->x(), m_label[m_layoutno]->y() + dy); m_vec_process_cmdcombox[m_layoutno]->move(m_vec_process_cmdcombox[m_layoutno]->x(), m_vec_process_cmdcombox[m_layoutno]->y() + dy); m_vec_process_devicecombox[m_layoutno]->move(m_vec_process_devicecombox[m_layoutno]->x(), m_vec_process_devicecombox[m_layoutno]->y() + dy); m_isautocombox[m_layoutno]->move(m_isautocombox[m_layoutno]->x(), m_isautocombox[m_layoutno]->y() + dy); m_vec_isdelete_processcfg_checkbox[m_layoutno]->move(m_vec_isdelete_processcfg_checkbox[m_layoutno]->x(), m_vec_isdelete_processcfg_checkbox[m_layoutno]->y() + dy); //qDebug() << "m_layoutno:" << m_layoutno << endl; if (m_firstmove) { QLayoutItem *item = m_processcfg_mainlayout->itemAt(m_layoutno); m_processcfg_mainlayout->removeItem(item); delete item; qDebug() << "MOVE" << endl; m_firstmove = false; } } else if (evt->type() == QEvent::MouseButtonRelease && isHover &&ismove) { //插入布局,获得鼠标松开左键的坐标值,判断鼠标此时在哪一个布局内,在它之前插入布局 QMouseEvent* e = static_cast<QMouseEvent*>(evt); int LayoutIndex = 0; //插入移动的布局 QHBoxLayout *layout = new QHBoxLayout; layout->addWidget(m_label[m_layoutno]); layout->addWidget(m_vec_process_cmdcombox[m_layoutno]); layout->addWidget(m_vec_process_devicecombox[m_layoutno]); layout->addWidget(m_isautocombox[m_layoutno]); layout->addWidget(m_vec_isdelete_processcfg_checkbox[m_layoutno]); //如何获得布局index?可以通过算术来得到 int layoutcount = m_processcfg_mainlayout->count(); //qDebug() << "layoutcount:" << layoutcount << endl; for (int k = 0; k < layoutcount; k++) { QHBoxLayout *hlayout = static_cast<QHBoxLayout *>(m_processcfg_mainlayout->itemAt(k)); if (!hlayout) { return true; } QRect rect = hlayout->geometry(); QHBoxLayout *hlayout1 = static_cast<QHBoxLayout *>(m_processcfg_mainlayout->itemAt(k+1)); //在移动到最下方的时候,因为在鼠标移动的时候已经删除布局 if (!hlayout1 && k == layoutcount-1) { LayoutIndex = k; break; } QRect rect1 = hlayout1->geometry(); if (e->pos().x()>rect.x() && (e->pos().y() > rect.y() && e->pos().y() < rect1.y() ) ) { LayoutIndex = k; break; } if (k==0 && e->pos().y()>0 && e->pos().y()<rect.y() ) { LayoutIndex = -1; break; } } m_processcfg_mainlayout->insertLayout(LayoutIndex+1, layout); QLabel *label = m_label[m_layoutno]; m_label.remove(m_layoutno); if (LayoutIndex == m_label.size()) { m_label.push_back(label); } else { m_label.insert(LayoutIndex + 1, label); } qDebug() << "TEST1 ==============================================" << endl; QComboBox *cmd = m_vec_process_cmdcombox[m_layoutno]; m_vec_process_cmdcombox.remove(m_layoutno); if (m_vec_process_cmdcombox.size() == LayoutIndex) { m_vec_process_cmdcombox.push_back(cmd); } else { m_vec_process_cmdcombox.insert(LayoutIndex + 1, cmd); } QComboBox *device = m_vec_process_devicecombox[m_layoutno]; m_vec_process_devicecombox.remove(m_layoutno); if (m_vec_process_devicecombox.size() == LayoutIndex) { m_vec_process_devicecombox.push_back(device); } else { m_vec_process_devicecombox.insert(LayoutIndex + 1, device); } qDebug() << "TEST2 ==============================================" << endl; QComboBox *isauto = m_isautocombox[m_layoutno]; m_isautocombox.remove(m_layoutno); if (m_isautocombox.size() == LayoutIndex) { m_isautocombox.push_back(isauto); } else { m_isautocombox.insert(LayoutIndex + 1, isauto); } QCheckBox *removecheck = m_vec_isdelete_processcfg_checkbox[m_layoutno]; m_vec_isdelete_processcfg_checkbox.remove(m_layoutno); if (m_vec_isdelete_processcfg_checkbox.size() == LayoutIndex) { m_vec_isdelete_processcfg_checkbox.push_back(removecheck); } else { m_vec_isdelete_processcfg_checkbox.insert(LayoutIndex + 1, removecheck); } qDebug() << "TEST3 ==============================================" << endl; //重置label的编号 int size = m_label.size(); for (int i=0;i<size;i++) { QString number = QString::number(i + 1, 10); m_label[i]->setText(number); } int testcount = m_processcfg_mainlayout->count(); //qDebug() << "testcount:" << testcount << endl; //删除正在移动的布局 //计算index的值 int index = -1; //1 获得鼠标点击左键的坐标值,2 获得label编号,循环判断鼠标此时在哪一个水平布局内,3 得到index,删除该水平布局 //如果选中,删除该行的控件 testcount = m_processcfg_mainlayout->count(); m_processcfg_widget->setLayout(m_processcfg_mainlayout); ui.ProcessCfgscrollArea->setWidget(m_processcfg_widget); isHover = false; m_firstmove = true; ismove = false; } return false; }
在所需页面调用installEventFilter函数,如下:
m_processcfg_widget->installEventFilter(this);