TreeView 中是靠信号与槽
connect(ui->treeView,SIGNAL(customContextMenuRequested(constQPoint&)), this,SLOT(onCustomContextMenuRequested(constQPoint&)))
实现TreeView内不同地方的右键菜单,文章见 http://blog.csdn.net/liukang325/article/details/22734735
TreeWidget 中是靠重构 contextMenuEvent(QContextMenuEvent*event)
函数实现不同地方的不同右键菜单的。具体代码如下:
h文件:
[cpp] view plaincopy
private slots:
void onGrpMenuTriggered(QAction *action)
void onMemberMenuTriggered(QAction *action)
void onAddAreaMenuTriggered(QAction *action)
private:
//grp menu
QMenu *m_grpMenu
//child menu
QMenu *m_memberMenu
QMenu *m_addAreaMenu
//grp action
QAction *m_grpAddOneMember
QAction *m_grpDeleteGrp
QAction *m_grpAddOneGrp
//child action
QAction *m_memberDelete
QAction *m_memberMove
QAction *m_memberSyncTime
//action
QAction *m_addAreaAction
QAction *m_grpFlush
QAction *m_addDev
void createItemMenu()//构造函数中调用此函数
cpp文件:
[cpp] view plaincopy
void MainWindow::createItemMenu()
{
m_grpMenu = new QMenu(this)
m_memberMenu = new QMenu(this)
m_addAreaMenu = new QMenu(this)
connect(m_grpMenu,SIGNAL(triggered(QAction *)),
this,SLOT(onGrpMenuTriggered(QAction *)))
connect(m_memberMenu,SIGNAL(triggered(QAction *)),
this,SLOT(onMemberMenuTriggered(QAction *)))
connect(m_addAreaMenu,SIGNAL(triggered(QAction *)),
this,SLOT(onAddAreaMenuTriggered(QAction *)))
m_grpAddOneMember = new QAction(tr("增加子区域"),this)
m_grpAddOneMember->setIcon(QIcon(":/image/add.png"))
m_grpAddOneGrp = new QAction(tr("增加设备"),this)
m_grpAddOneGrp->setIcon(QIcon(":/image/add.png"))
m_grpDeleteGrp = new QAction(tr("删除区域"),this)
m_grpDeleteGrp->setIcon(QIcon(":/image/delete.png"))
m_memberDelete = new QAction(tr("删除设备"),this)
m_memberDelete->setIcon(QIcon(":/image/delete.png"))
m_memberMove = new QAction(tr("移动设备"),this)
m_memberMove->setIcon(QIcon(":/image/next.png"))
m_memberSyncTime = new QAction(tr("同步时间"),this)
m_memberSyncTime->setIcon(QIcon(":/image/move.png"))
m_addAreaAction = new QAction(tr("增加区域"),this)
m_addAreaAction->setIcon(QIcon(":/image/add.png"))
m_addDev = new QAction(tr("增加设备"),this)
m_addDev->setIcon(QIcon(":/image/add.png"))
m_grpFlush = new QAction(tr("刷新列表"),this)
m_grpFlush->setIcon(QIcon(":/image/update.png"))
}
//重构contextMenuEvent函数,记得#include <QContextMenuEvent>
void MainWindow::contextMenuEvent(QContextMenuEvent *event)
{
QTreeWidgetItem *item = ui->treeWidget->currentItem()
if(item == NULL)
{
qDebug()<<"空白处"
if (m_addAreaMenu->isEmpty())
{
//增加区域
m_addAreaMenu->addAction(m_addAreaAction)
m_addAreaMenu->addAction(m_addDev)
m_addAreaMenu->addAction(m_grpFlush)
}
//菜单出现的位置为当前鼠标的位置
m_addAreaMenu->exec(QCursor::pos())
}
else if(ui->treeWidget->currentItem()->childCount() >0)
{
if (m_grpMenu->isEmpty())
{
//增加子区域
m_grpMenu->addAction(m_grpAddOneMember)
//删除区域
m_grpMenu->addAction(m_grpDeleteGrp)
m_grpMenu->addAction(m_grpAddOneGrp)
}
m_grpMenu->exec(QCursor::pos())
}
else if(ui->treeWidget->currentItem()->childCount() == 0)
{
if (m_memberMenu->isEmpty())
{
//删除设备
m_memberMenu->addAction(m_memberDelete)
//移动设备
m_memberMenu->addAction(m_memberMove)
//同步时间
m_memberMenu->addAction(m_memberSyncTime)
}
m_memberMenu->exec(QCursor::pos())
}
event->accept()
}
void MainWindow::onGrpMenuTriggered(QAction *action)
{
if (action == m_grpAddOneMember)
{//增加子区域
}
else if (action == m_grpDeleteGrp)
{//删除区域
}
else if(action == m_grpAddOneGrp)
{
}
}
void MainWindow::onMemberMenuTriggered(QAction *action)
{
if (action == m_memberDelete)
{//删除设备
}
else if(action == m_memberMove)
{//移动设备
}
else if(action == m_memberSyncTime)
{//同步时间
}
}
void MainWindow::onAddAreaMenuTriggered(QAction *action)
{
if (action == m_addAreaAction)
{//增加区域
}
if(action == m_addDev)
{//增加设备
}
if(action == m_grpFlush)
{//刷新
}
}
树型结构的基本用法:
[cpp] view plaincopy
void MainWindow::createTreeWidget()
{
QIcon icon
icon.addPixmap(QPixmap(":/image/openStatus.png"), QIcon::Normal, QIcon::On)//节点打开状态
icon.addPixmap(QPixmap(":/image/closeStatus.png"), QIcon::Normal, QIcon::Off)//节点关闭状态
ui->treeWidget->setColumnCount(1)
QStringList headers
headers <<QObject::tr("管理")
ui->treeWidget->setHeaderLabels(headers)
QStringList rootName_1
rootName_1 <<QObject::tr("常用文件夹")
QTreeWidgetItem *rootItem_1 = new QTreeWidgetItem(ui->treeWidget, rootName_1)
// rootItem_1->setIcon(0, QIcon(":/image/add.png"))//增加静态图标
rootItem_1->setIcon(0,icon)
QStringList childName_1_1
childName_1_1 <<"所有未读"
QTreeWidgetItem *childItem_1_1 = new QTreeWidgetItem(rootItem_1, childName_1_1)
rootItem_1->addChild(childItem_1_1)
QStringList childName_1_2
childName_1_2 <<QObject::tr("置顶邮件")
QTreeWidgetItem *childItem_1_2 = new QTreeWidgetItem(rootItem_1, childName_1_2)
rootItem_1->addChild(childItem_1_2)
QStringList rootName_2
rootName_2 <<QObject::tr("我的邮箱")
QTreeWidgetItem *rootItem_2 = new QTreeWidgetItem(ui->treeWidget, rootName_2)
rootItem_2->setIcon(0,icon)
QStringList childName_2_1
childName_2_1 <<QObject::tr("收件箱")
QTreeWidgetItem *childItem_2_1 = new QTreeWidgetItem(rootItem_2, childName_2_1)
rootItem_2->addChild(childItem_2_1)
QStringList childName_2_2
childName_2_2 <<QObject::tr("草稿箱")
QTreeWidgetItem *childItem_2_2 = new QTreeWidgetItem(rootItem_2, childName_2_2)
rootItem_2->addChild(childItem_2_2)
QStringList childName_2_3
childName_2_3 <<QObject::tr("发件箱")
QTreeWidgetItem *childItem_2_3 = new QTreeWidgetItem(rootItem_2, childName_2_3)
rootItem_2->addChild(childItem_2_3)
ui->treeWidget->addTopLevelItem(rootItem_1)
ui->treeWidget->addTopLevelItem(rootItem_2)
QStringList childName_1_2_1
childName_1_2_1 <<"测试"
QTreeWidgetItem *childItem_1_2_1 = new QTreeWidgetItem(childItem_1_2, childName_1_2_1)
childItem_1_2->addChild(childItem_1_2_1)
}
另一篇TreeWidget 的用法,更加清晰明了的实现树状结构:http://blog.csdn.net/liukang325/article/details/13768523
补充:
childItem_1_2_1->setForeground(0,QBrush(QColor(Qt::blue)))
// 可将某一项的字体变颜色!
在自定义的delegate中检查if(index.data(Qt::UserRole).toString() == "your value")的值,该值在QTreeWidget中要预先设定。这样就可以在让指定QTreeWidgetItem->setData(1, (Qt::UserRole), "your value")的QTreeWidgetItem使用相对应的delegate了.就在构造函数里面加上以下两行代码即可:
//根据内容自动设置列宽
ui->treeWidget->header()->setResizeMode(QHeaderView::ResizeToContents)
ui->treeWidget->header()->setStretchLastSection(false)
在解决完上述问题后,又遇到一个问题,就是用鼠标左键或者右键单击QTreeWidget里面的选项时,水平滚动条会自动跑到最左边,双击不会出现这个问题,详细查阅了QTreeWidget的实现代码,在其父类中有个事件处理函数void QAbstractItemView::timerEvent(QTimerEvent *event),加了一个滚动处理,这里真是有点晕了,它的注释就是“we only get here if there was no double click”,大家可以看下这里为什么要加这个滚动处理。
解决方法如下(我已经对QTreeWidget进行了二次封装,就直接在这上面改的,不封装照样可以实现,原理是一样的):
1.加两个变量,记录是否有选项被点击,一个记录点击时的水平滚动条位置
bool m_isItemClicked
int m_horizontalScrollBarPos
2.对两个事件进行处理
connect(ui->treeWidget->horizontalScrollBar(), SIGNAL(valueChanged(int)), this,SLOT(scrollbarchange(int)))
void MainWindow::on_treeWidget_itemClicked(QTreeWidgetItem *item, int column)
{
m_isItemClicked = true
m_horizontalScrollBarPos = ui->treeWidget->horizontalScrollBar()->sliderPosition()
}
void MainWindow::scrollbarchange(int value)
{
if (m_isItemClicked)
{
ui->treeWidget->horizontalScrollBar()->setValue(m_horizontalScrollBarPos)
m_isItemClicked = false
}
}
1.继承QTreewidget重新实现他的mouseReleaseEvent方法,为什么是release方法,因为源码里面mousePressEvent方法用来绘制treeWidget,而release方法则会发送出点击事件的信号#ifndefTREEWIDGET_H
#define TREEWIDGET_H
#ifndef TREEWIDGET_H
#define TREEWIDGET_H
#include <QWidget>
#include <QTreeWidget>
#include <QMouseEvent>
class QTreeWidget2 : public QTreeWidget
{
Q_OBJECT
public:
explicit QTreeWidget2( QWidget *parent = 0 )
protected:
void mouseReleaseEvent (QMouseEvent *event)
}
#endif // TREEWIDGET_H
2.实现
#include "treeWidget.h"
QTreeWidget2::QTreeWidget2( QWidget *parent)
:QTreeWidget(parent)
{
}
void QTreeWidget2::mouseReleaseEvent (QMouseEvent *event)
{
if (event->button () &Qt::RightButton )
{
emit customContextMenuRequested( event->pos ())
}else if (event->button () &Qt::LeftButton){
emit itemClicked(itemFromIndex (indexAt ( event->pos () )),indexAt ( event->pos () ).column ())
}
}
3.测试
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTreeWidgetItem>
class QTreeWidget2
static const int itemtype1 = QTreeWidgetItem::Type
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow( QWidget *parent = 0 )
public slots:
void setTest2(const QPoint &pos)
void setTest(QTreeWidgetItem*item,int column)
private:
QTreeWidget2 *treeWidget
QTreeWidgetItem *currentItem
}
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "treeWidget.h"
#include <QMessageBox>
#include <QtDebug>
MainWindow::MainWindow(QWidget *parent):
QMainWindow(parent)
{
treeWidget = new QTreeWidget2
treeWidget->setContextMenuPolicy(Qt::CustomContextMenu)
treeWidget->setHeaderLabel ( tr("资源列表") )
QTreeWidgetItem *root = new QTreeWidgetItem( treeWidget )
root->setText (0,tr("root"))
QTreeWidgetItem *item = new QTreeWidgetItem( root )
item->setText (0,tr("a"))
QTreeWidgetItem *item1 = new QTreeWidgetItem( item )
item1->setText (0,tr("b"))
QTreeWidgetItem *item2 = new QTreeWidgetItem( item1 )
item2->setText (0,tr("c"))
connect( treeWidget,SIGNAL(customContextMenuRequested( const QPoint &)),
this,SLOT(setTest2(const QPoint &)))
connect( treeWidget,SIGNAL(itemClicked(QTreeWidgetItem*,int)),
this,SLOT(setTest(QTreeWidgetItem*,int)))
setCentralWidget ( treeWidget )
resize ( 500,400 )
}
void MainWindow::setTest2(const QPoint &pos)
{
currentItem = treeWidget->itemAt(pos)
if ( currentItem == NULL )
return
QMessageBox::warning (this,tr("test"),tr("hello"))
}
void MainWindow::setTest(QTreeWidgetItem*item,int column)
{
QMessageBox::warning (this,tr("asd"),tr("sd"))
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)