久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

qt自定義樹形控件之一(控件的自定義)

 dafuweng2011 2023-03-05 發(fā)布于北京

前言

qt中定義了很多簡單實(shí)用的數(shù)據(jù)展示視圖控件,,比如表格和樹形表等,。由于表格的結(jié)構(gòu)和數(shù)據(jù)庫存儲(chǔ)類似,所以qt提供一個(gè)類來實(shí)現(xiàn)表格視圖和數(shù)據(jù)庫的直接連接,。但是對于樹形結(jié)構(gòu),在數(shù)據(jù)庫中的表達(dá)和視圖的表達(dá)有較大差異,qt尚未提供相關(guān)的功能,。
本文的背景是要做一個(gè)模板的管理功能。由于模板的組織方式是層級(jí)結(jié)構(gòu)(樹形結(jié)構(gòu)),,所以要用到樹形控件,。又要求具有持久化保存模板的功能,將來還可能擴(kuò)展的遠(yuǎn)程的模板統(tǒng)一管理,,所以使用數(shù)據(jù)庫進(jìn)行模板的保存,。

所以本文要介紹的是筆者最近做的一個(gè)基于QTreeWidget的自定義樹形控件,,可以實(shí)現(xiàn)右擊菜單,,每次更改樹結(jié)構(gòu)后實(shí)時(shí)修改數(shù)據(jù)庫,初始化時(shí)從數(shù)據(jù)庫讀取樹形結(jié)構(gòu)并顯示,。
具體效果如下:
在這里插入圖片描述
但由于內(nèi)容比較多,,筆者打算分為兩篇進(jìn)行介紹,首先在這一篇中,,介紹qt控件的繼承以及在界面中把控件提升(promete)為自定義的控件,。在下一篇中,介紹如何把對樹的操作寫入數(shù)據(jù)庫以及如何在初始化過程中從數(shù)據(jù)庫讀取樹結(jié)構(gòu),。

具體實(shí)現(xiàn)

控件類的定義

首先,,自定義的控件要繼承自QTreeWidget,然后需要添加一些增加根節(jié)點(diǎn),,刪除節(jié)點(diǎn),,增加目錄,增加模板,,重命名節(jié)點(diǎn)等想要實(shí)現(xiàn)功能的槽函數(shù),,這些槽函數(shù)會(huì)在后面右擊菜單中調(diào)用,。右擊菜單在qt中是一個(gè)action,,需要定義幾個(gè)QAction變量,。initTreeWidget()函數(shù)在程序啟動(dòng)時(shí)從數(shù)據(jù)庫讀取樹形結(jié)構(gòu),但是本文只介紹控件的自定義相關(guān)內(nèi)容,,這個(gè)函數(shù)中會(huì)生成一個(gè)固定的樹。

class QMyTreeWidget : public QTreeWidget
{
    Q_OBJECT
public:
    explicit QMyTreeWidget(QWidget *parent = 0);

private slots:
    void on_treeWidget_customContextMenuRequested(const QPoint &pos);
    void addRootNode();
    void deleteAllNodes();
    void addCategory();
    void addTemplate();

    void deleteNode();
    void reNameNode();

private:

    void initTreeWidget();

    QTreeWidgetItem* curItem;  //當(dāng)前被右擊的item
    //空白地方點(diǎn)擊
    QAction *addRootNodeAction;
    QAction *deleteAllNodesAction;

    //節(jié)點(diǎn)上點(diǎn)擊
    QAction *addCategoryAction;
    QAction *addTemplateAction;
    QAction *deleteNodeAction;
    QAction *reNameNodeAction;

};

action和槽函數(shù)連接

addRootNodeAction = new QAction("&addRootNode", this);
deleteAllNodesAction = new QAction("&deleteAllNodes", this);

addCategoryAction = new QAction("&addCategory", this);
addTemplateAction = new QAction("&addTemplate", this);

deleteNodeAction = new QAction("&deleteNode", this);
reNameNodeAction = new QAction("&reNameNode", this);

connect(addRootNodeAction,SIGNAL(triggered()),this,SLOT(addRootNode()));
connect(deleteAllNodesAction,SIGNAL(triggered()),this,SLOT(deleteAllNodes()));

connect(addCategoryAction,SIGNAL(triggered()),this,SLOT(addCategory()));
connect(addTemplateAction,SIGNAL(triggered()),this,SLOT(addTemplate()));

connect(deleteNodeAction,SIGNAL(triggered()),this,SLOT(deleteNode()));
connect(reNameNodeAction,SIGNAL(triggered()),this,SLOT(reNameNode()));

右擊菜單實(shí)現(xiàn)

首先,,需要把控件的contextMenuPolicy選項(xiàng)設(shè)為CustomContextMenu
然后把右擊菜單動(dòng)作和槽函數(shù)連接起來

connect(this,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(on_treeWidget_customContextMenuRequested(QPoint)));

在槽函數(shù)中實(shí)現(xiàn)不同位置點(diǎn)擊彈出不同的菜單

void QMyTreeWidget::on_treeWidget_customContextMenuRequested(const QPoint &pos)
{
    curItem=this->itemAt(pos);  //獲取當(dāng)前被點(diǎn)擊的節(jié)點(diǎn)

    //在空白位置點(diǎn)擊,,彈出菜單:添加根節(jié)點(diǎn),刪除所有模板,。
    if(curItem == NULL)
    {
        QMenu *popMenu =new QMenu(this);//定義一個(gè)右鍵彈出菜單
        popMenu->addAction(addRootNodeAction);
        popMenu->addAction(deleteAllNodesAction);
        popMenu->exec(QCursor::pos());
    }
    else{
        QVariant var = curItem->data(0,Qt::UserRole);
        qDebug() << var.toString() << endl;
        //讀取表,,對isCategory字段進(jìn)行判斷
        if(1)   //選中目錄
        {
            qDebug() << "category" << endl;
            QMenu *popMenu =new QMenu(this);//定義一個(gè)右鍵彈出菜單
            popMenu->addAction(addCategoryAction);
            popMenu->addAction(addTemplateAction);
            popMenu->addAction(deleteNodeAction);
            popMenu->addAction(reNameNodeAction);
            popMenu->exec(QCursor::pos());
        }
        else     //選中模板
        {
            qDebug() << "template" << endl;
            QMenu *popMenu =new QMenu(this);//定義一個(gè)右鍵彈出菜單
            popMenu->addAction(deleteNodeAction);
            popMenu->addAction(reNameNodeAction);
            popMenu->exec(QCursor::pos());
        }
    }
}

槽函數(shù)實(shí)現(xiàn)過程

重命名節(jié)點(diǎn):

void QMyTreeWidget::reNameNode()
{
    qDebug() << "reNameNode" << endl;

    QInputDialog dia(this);
    dia.setWindowTitle("Input Dialog");
    dia.setLabelText("Please input text:");
    dia.setInputMode(QInputDialog::TextInput);//可選參數(shù):DoubleInput  TextInput

    if(dia.exec() == QInputDialog::Accepted)
    {
       qDebug() << dia.textValue();
       curItem->setText(0,dia.textValue());

       //更新數(shù)據(jù)庫
       //curTtem->data   dia.textValue()
    }
}

刪除節(jié)點(diǎn):

void QMyTreeWidget::deleteNode()
{
    qDebug() << "deleteNode" << endl;
    //curItem->data()  當(dāng)前UUID  刪除該索引

    QTreeWidgetItem* parent = curItem->parent();
    if(parent == NULL)
    {
        //得到索引
        int index = 0;
        int count = this->topLevelItemCount();
        for(int i = 0;i<count;i++)
        {
            //QTreeWidget
            //ui->treeWidget->TopLevelItem()
            QTreeWidgetItem* temp = this->topLevelItem(i);
            if(curItem->data(0,Qt::UserRole).toString() == temp->data(0,Qt::UserRole).toString())
            {
                index = i;
            }
        }
        this->takeTopLevelItem(index);
    }
    else
        parent->removeChild(curItem);

    //刪除數(shù)據(jù)庫一行
    //curTtem->data
}

增加一個(gè)葉節(jié)點(diǎn),,該節(jié)點(diǎn)下不能再添加節(jié)點(diǎn)

void QMyTreeWidget::addTemplate()
{
    qDebug() << "addTemplate" << endl;
    //新節(jié)點(diǎn)ID     根       模板名稱  顏色值    是否目錄
    //隨機(jī)UUID  當(dāng)前UUID   title   colors      0
    //curItem->data()  當(dāng)前UUID
    QTreeWidgetItem *temp=new QTreeWidgetItem(curItem);

    QInputDialog dia(this);
    dia.setWindowTitle("Input Dialog");
    dia.setLabelText("Please input text:");
    dia.setInputMode(QInputDialog::TextInput);//可選參數(shù):DoubleInput  TextInput

    if(dia.exec() == QInputDialog::Accepted)
    {
       qDebug() << dia.textValue();
       temp->setText(0,dia.textValue());

       QVariant var;
       QString str = QUuid::createUuid().toString();
       var.setValue(str);
       temp->setData(0,Qt::UserRole,var);
    }
}

添加一個(gè)目錄,,該節(jié)點(diǎn)可以有子節(jié)點(diǎn)

void QMyTreeWidget::addCategory()
{
    qDebug() << "addCategory" << endl;
    //在TEMPLATE表中新加一行
    //新節(jié)點(diǎn)ID     根       模板名稱  顏色值     是否目錄
    //隨機(jī)UUID  當(dāng)前UUID   title   colors       1
    //curItem->data()  當(dāng)前UUID

    QTreeWidgetItem *temp=new QTreeWidgetItem(curItem);

    QInputDialog dia(this);
    dia.setWindowTitle("Input Dialog");
    dia.setLabelText("Please input text:");
    dia.setInputMode(QInputDialog::TextInput);//可選參數(shù):DoubleInput  TextInput

    if(dia.exec() == QInputDialog::Accepted)
    {
       qDebug() << dia.textValue();
       temp->setText(0,dia.textValue());

       QVariant var;
       QString str = QUuid::createUuid().toString();
       var.setValue(str);
       temp->setData(0,Qt::UserRole,var);
	   
	   //數(shù)據(jù)庫添加一行
	   //UUID: str    Title:dia.textValue()
    }
}

刪除所有節(jié)點(diǎn):

void QMyTreeWidget::deleteAllNodes()
{
    qDebug() << "deleteAllNodes" << endl;
	this->clear();
    //清空數(shù)據(jù)庫表
 
}

添加根節(jié)點(diǎn),在整個(gè)樹為空時(shí),,在任意位置點(diǎn)擊可以選擇

void QMyTreeWidget::addRootNode()
{
    qDebug() << "addRootNode" << endl;
    //在TEMPLATE表中新加一行
    //新節(jié)點(diǎn)ID   根   模板名稱  顏色值    是否目錄
    //隨機(jī)UUID  -1   title   colors     1
    QTreeWidgetItem *temp=new QTreeWidgetItem(this);

    QInputDialog dia(this);
    dia.setWindowTitle("Input Dialog");
    dia.setLabelText("Please input text:");
    dia.setInputMode(QInputDialog::TextInput);//可選參數(shù):DoubleInput  TextInput

    if(dia.exec() == QInputDialog::Accepted)
    {
       qDebug() << dia.textValue();
       temp->setText(0,dia.textValue());

       QVariant var;
       QString str = QUuid::createUuid().toString();
       var.setValue(str);
       temp->setData(0,Qt::UserRole,var);
    }
}

初始化一個(gè)固定的樹

void QMyTreeWidget::initTreeWidget()
{
    //初始化時(shí)從數(shù)據(jù)庫讀取當(dāng)前樹結(jié)構(gòu),,需要使用遞歸的方法

    //initTreeWidget() 的實(shí)現(xiàn)
    this->clear();
    //ui->treeWidget->clear();
    this->setHeaderHidden(true);
    //ui->treeWidget->setHeaderHidden(true);
    //第一組
    QTreeWidgetItem *group1=new QTreeWidgetItem(this);
    group1->setText(0,"group1");
    QVariant var;
    QString str = QUuid::createUuid().toString();
    var.setValue(str);
    group1->setData(0,Qt::UserRole,var);


    QTreeWidgetItem *item11=new QTreeWidgetItem(group1);
    item11->setText(0,"item11");
    QTreeWidgetItem *newnew=new QTreeWidgetItem(item11);
    newnew->setText(0,"newnew");

    QTreeWidgetItem *item12=new QTreeWidgetItem(group1);
    item12->setText(0,"item12");
    QTreeWidgetItem *item13=new QTreeWidgetItem(group1);
    item13->setText(0,"item13");

    //第二組
    QTreeWidgetItem *group2=new QTreeWidgetItem(this);
    group2->setText(0,"group2");

    QTreeWidgetItem *item21=new QTreeWidgetItem(group2);
    item21->setText(0,"item21");

    QTreeWidgetItem *item22=new QTreeWidgetItem(group2);
    item22->setText(0,"item22");

    QTreeWidgetItem *item23=new QTreeWidgetItem(group2);
    item23->setText(0,"item23");
    item23->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
    item23->setCheckState(0,Qt::Unchecked);
}

至此,控件的自定義已經(jīng)完成,。這個(gè)demo可以實(shí)現(xiàn)右鍵操作,,并且控件結(jié)構(gòu)隨之變化。但是在程序重新啟動(dòng)后,,上次更改過的內(nèi)容全部丟失,。要解決問題,需要用數(shù)據(jù)庫保存樹結(jié)構(gòu),。這將在下一篇中進(jìn)行介紹,。預(yù)知后事如何,請聽下回分解,。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多