Qt Designer 的出現,讓我們很容易通過控件的方式設計出我們自己的軟件界面。但有時,Designer提供給我們的控件,無法滿足我們的需求,需要根據實際情況採取繼承的方式進行設計。
本文通過QListWidget和QTreeWidget之間的拖曳進行說明。工程文件
如圖1個工程文件
3個頭文件
4個源文件
1個form文件
各文件源碼
1.根據實際情況,創建類
//qlistwidget_ex.h #ifndef QLISTWIDGET_EX_H #define QLISTWIDGET_EX_H #include <QListWidget> #include <QPoint> #include <QMouseEvent> class QListWidget_ex : public QListWidget { Q_OBJECT public: QListWidget_ex(); protected: void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *e); private: QPoint m_beginPos; }; #endif // QLISTWIDGET_EX_H
//qlistwidget_ex.cpp #include "qlistwidget_ex.h" #include <QDrag> #include <QMimeData> #include <QDebug> #include <QImage> #include <QApplication> QListWidget_ex::QListWidget_ex() { } void QListWidget_ex::mousePressEvent(QMouseEvent *event) { if(event->button()==Qt::LeftButton) { m_beginPos=event->pos(); //qDebug()<<m_beginPos.rx()<<"+"<<m_beginPos.ry(); } QListWidget::mousePressEvent(event); } void QListWidget_ex::mouseMoveEvent(QMouseEvent *e) { if(e->buttons()&Qt::LeftButton) { int nDistance=(e->pos()-m_beginPos).manhattanLength(); if(nDistance>=QApplication::startDragDistance()) { // qDebug()<<nDistance; QListWidgetItem *item=currentItem(); if(item) { QMimeData *mimeData=new QMimeData; mimeData->setText(item->text()); // qDebug()<<mimeData->text(); QDrag *drag=new QDrag(this); drag->setMimeData(mimeData); QImage image;//(128,128,QImage::Format_ARGB32); if(image.load("../images/qt.png")==true) drag->setPixmap(QPixmap::fromImage(image)); if(Qt::MoveAction==drag->exec(Qt::MoveAction)) { delete item; // qDebug()<<"delete item"; } } } } QListWidget::mouseMoveEvent(e); }
//qtreewidget_ex.h class Qtreewidget_ex : public QTreeWidget { Q_OBJECT public: explicit Qtreewidget_ex(); protected: void dragEnterEvent(QDragEnterEvent *event); void dragMoveEvent(QDragMoveEvent *event); void dropEvent(QDropEvent *event); };
//qtreewidget_ex.cpp Qtreewidget_ex::Qtreewidget_ex() { setAcceptDrops(true); } void Qtreewidget_ex::dragEnterEvent(QDragEnterEvent *event) { QListWidget_ex *source=qobject_cast<QListWidget_ex*>(event->source()); if(source) { event->setDropAction(Qt::MoveAction); event->accept(); //qDebug()<<source; } } void Qtreewidget_ex::dragMoveEvent(QDragMoveEvent *event) { QListWidget_ex *source=qobject_cast<QListWidget_ex*>(event->source()); if(source) { event->setDropAction(Qt::MoveAction); event->accept(); } } void Qtreewidget_ex::dropEvent(QDropEvent *event) { QListWidget_ex *source=qobject_cast<QListWidget_ex*>(event->source()); if(source) { QModelIndex currentId=indexAt(event->pos()); if(currentId.isValid()) { QTreeWidgetItem *item=itemFromIndex(currentId); model()->insertRow(item->childCount(),currentId); QModelIndex childId=model()->index(item->childCount()-1,0,currentId); model()->setData(childId,QVariant(event->mimeData()->text()),Qt::DisplayRole); event->setDropAction(Qt::MoveAction); event->accept(); } } }
2.寫MainWindow.cpp文件
//mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include <QGridLayout> #include <QHBoxLayout> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); m_listWidget=new QListWidget_ex; m_treeWidget=new Qtreewidget_ex; QWidget *centerWindow = new QWidget; this->setCentralWidget(centerWindow); QHBoxLayout *hLayout=new QHBoxLayout; m_listWidget->addItem("drag1"); m_listWidget->addItem("drag2"); m_listWidget->addItem("drag3"); QTreeWidgetItem *item=new QTreeWidgetItem(QStringList(QString("first"))); QTreeWidgetItem *item2=new QTreeWidgetItem(QStringList(QString("second"))); m_treeWidget->setHeaderLabel("treeWidget"); m_treeWidget->addTopLevelItem(item); m_treeWidget->addTopLevelItem(item2); hLayout->addWidget(m_listWidget); hLayout->addWidget(m_treeWidget); centerWindow->setLayout(hLayout); } MainWindow::~MainWindow() { delete ui; }
3.由於重寫了控件,main.cpp保存原樣即可
//main.cpp #include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
程序截圖
小結
由於本人當時對Qt的理解不夠,沒明白如何添加相應的控件到UI,特此記錄一下。