QListWidget和QToolButton
Item组件
Qt中用于项(Item)处理的组件有两类,一类是Item Views,包括QListView、QTreeView、QTableView、QColumnView等;另一类是Item Widgets,包括QListWidget、QTreeWidget和QTableWidget。
Item Widgets:
QListWidget的每一行是一个项,QTreeWidget的每个节点是一个项,QTableWidget的每一个单元格是一个项。一个项存储了文字、文字的格式、自定义数据等。
Qt中的菜单栏中的Action动作与按键关联:
按钮都使用QToolButton组件,QToolButton有一个setDefaultAction()函数,可以使其与一个Action关联,按钮的文字、图标、ToolTip都将自动设置为与关联的Action一致,单击一个QToolButton按钮就是执行Action的槽函数,与工具栏上的按钮一样。
按键中增加菜单栏就可以了
QToolButton还有一个setMenu()函数,可以为其设置一个下拉式菜单,配合QToolButton的一些属性设置,可以有不同的下拉菜单效果。工具栏上的“项选择”直接显示下拉菜单,而在列表框上方的“项选择”按钮,只有单击右侧的向下箭头才弹出下拉菜单,直接单击按钮会执行按钮关联的Action的代码。
要用代码实现的部分,就是为界面上的各ToolButton按钮设置关联的Action,在工具栏上动态添加一个ToolButton,并设置其下拉菜单功能。
QToolBox
主要的属性设置如下:
currentIndex,当前分组编号,第1个分组的编号是0,通过改变这个值,可以选择不同的分组页面。
currentItemText,当前分组的标题。
currentItemName,当前分组的对象名称。
currentItemIcon,为当前分组设置一个图标,显示在文字标题的左侧。
QTabWidget
主要的属性设置如下:
tabPosition:页标签的位置,东、西、南、北四个方位中选择一个。
currentIndex:当前页的编号。
currentTabText:当前页的标题。
currentTabName:当前页的对象名称。
currentTabIcon:可以为当前页设置一个图标,显示在文字标题的左侧。
QSplitter设计分割界面
是工具栏中的分裂器。同时选择不同的两个组件,可以就可以为这两个组件创建一个水平分割的布局组件splitter。在主窗口构造函数里使用下面一行语句就可以使splitter填充满整个工作区。
setCentralWidget(ui->splitter);
QListWidget
QListWidget是存储多个项的列表组件,每个项是一个QListWidgetItem类型的对象。
可以在界面上设置,在这个编辑器里可以增加、删除、上移、下移列表项,可以设置每个项的属性,包括文字内容、字体、文字对齐方式、背景色、前景色等。
比较重要的是其flags属性,用于设置项的一些标记,这些标记是枚举类型Qt::ItemFlag的具体值,包括以下几种:
Selectable:项是否可被选择,对应枚举值Qt::ItemIsSelectable。
Editable:项是否可被编辑,对应枚举值Qt:: ItemIsEditable。
DragEnabled:项是否可以被拖动,对应枚举值Qt:: ItemIsDragEnabled。
DropEnabled:项是否可以接收拖放的项,对应枚举值Qt:: ItemIsDropEnabled。
UserCheckable:项是否可以被复选,若为true,项前面出现一个CheckBox,对应枚举值Qt:: ItemIsUserCheckable。
Enabled:项是否被使能,对应枚举值Qt:: ItemIsEnabled。
Tristate:是否允许Check的第三种状态,若为false,则只有checked和unChecked两种状态,对应枚举值Qt::ItemIsAutoTristate。
在代码中设置项的flags属性时,使用函数setFlags(),例如:
aItem->setFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled);
创建Action
采用Action设计工具栏,并且将Action用于QToolButton按钮。
actSelPopMenu用于“项选择”的ToolButton按钮,也就是窗口上具有下拉菜单的两个按钮。将actSelPopMenu的功能设置为与actSelInvs完全相同,在“Signals &Slots Editor”里设置这两个Action关联(如图4-12所示),这样,执行actSelPopMenu就是执行actSelInvs。
QListWidget的代码的操作
点击按键初始化列表
void MainWindow::on_actListIni_triggered()
{ //初始化列表
QListWidgetItem *aItem; //每一行是一个QListWidgetItem
QIcon aIcon;
aIcon.addFile(":/images/icons/check2.ico");
bool chk=ui->chkBoxListEditable->isChecked();//是否可编辑
ui->listWidget->clear();
for (int i=0; i<10; i++)
{
QString str=QString::asprintf("Item %d",i);
aItem=new QListWidgetItem();
aItem->setText(str); //设置文字标签
aItem->setIcon(aIcon); //设置图标
aItem->setCheckState(Qt::Checked); //设置为选中状态
if (chk) //可编辑, 设置flags
aItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable
|Qt::ItemIsUserCheckable |Qt::ItemIsEnabled);
else//不可编辑, 设置flags
aItem->setFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable
|Qt::ItemIsEnabled);
ui->listWidget->addItem(aItem); //增加一个项
}
}
/*列表框里一行是一个项,是一个QListWidgetItem类型的对象,向列表框添加一个项,就需要创建一个QListWidgetItem
类型的实例aItem,然后设置aItem的一些属性,再用QListWidget:: AddItem()函数将该aItem添加到列表框里。*/
点击按键插入项
void MainWindow::on_actListInsert_triggered()
{ //插入一个项
//插入项使用QListWidget的insertItem(int row, QListWidgetItem *item)函数,在某一行row的前面插入一个
//QListWidgetItem对象item,也需要先创建这个item,并设置好其属性。actListInsert实现这个功能,其槽函数代码如下:
QIcon aIcon;
aIcon.addFile(":/images/icons/check2.ico");
bool chk=ui->chkBoxListEditable->isChecked();
QListWidgetItem* aItem=new QListWidgetItem("New Inserted Item");
aItem->setIcon(aIcon);
aItem->setCheckState(Qt::Checked);
//这里设置新插入的项是可选择的、能用的、可复选的。还根据界面设置,确定项是否可编辑。
if (chk)
aItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable
|Qt::ItemIsUserCheckable |Qt::ItemIsEnabled);
else
aItem->setFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable
|Qt::ItemIsEnabled);
ui->listWidget->insertItem(ui->listWidget->currentRow(),aItem);
}
删除项和清空列表
//删除当前项的actListDelete的槽函数代码如下:
void MainWindow::on_actListDelete_triggered()
{ //删除当前项
int row=ui->listWidget->currentRow();
QListWidgetItem* aItem=ui->listWidget->takeItem(row);
delete aItem; //手工删除对象
}
//takeItem()函数只是移除一个项,并不删除项对象,所以还需要用delete从内存中删除它。
//要清空列表框的所有项,只需调用QListWidget::clear()函数即可。
遍历并选择项
界面上有“全选”“全不选”“反选”3个按钮,由3个Action实现,用于遍历列表框里的项,设置选择状态。用于“全选”的actSelALL的槽函数代码如下:
void MainWindow::on_actSelALL_triggered()
{ //全选
int cnt=ui->listWidget->count();//个数
for (int i=0; i<cnt; i++)
{
QListWidgetItem *aItem=ui->listWidget->item(i);//获取一个项
aItem->setCheckState(Qt::Checked);//设置为选中
}
/*函数QListWidgetItem::setCheckState(Qt::CheckState state)设置列表项的复选状态,枚举类型 Qt::CheckState有3种取值。
Qt::Unchecked,不被选中。
Qt::PartiallyChecked,部分选中。在目录树中的节点可能出现这种状态,比如其子节点没有全部被勾选时。
Qt::Checked,被选中。*/
QListWidget的常用信号
QListWidget在当前项切换时发射两个信号,只是传递的参数不同。
currentRowChanged(int currentRow):传递当前项的行号作为参数。
currentItemChanged(QListWidgetItem current, QListWidgetItem previous):传递两个QList WidgetItem对象作为参数,current表示当前项,previous是前一项。
当前项的内容发生变化时发射信号currentTextChanged(const QString ¤tText)。
为listWidget的currentItemChanged()信号编写槽函数,代码如下:
void MainWindow::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{ //listWidget当前选中项发生变化
QString str;
if (current != NULL)
{
if (previous==NULL)
str="当前项:"+current->text();
else
str="前一项:"+previous->text()+"; 当前项:"+current->text();
ui->editCutItemText->setText(str);
}
}
//响应代码里需要判断current和previous指针是否为空,否则使用对象时可能出现访问错误。
QToolButton与下拉式菜单
1.QToolButton关联QAction
在ToolBox里放置了几个QToolButton按钮,希望它们实现与工具栏上的按钮相同的功能;列表框上方放置了几个QToolButton按钮,希望它们完成列表项选择的功能。
这些功能都已经有相应的Actions来实现,要让ToolButton按钮实现这些功能,无需再为其编写代码,只需设置一个关联的QAction对象即可。
QToolButton有一个函数setDefaultAction(),其函数原型为:
void QToolButton::setDefaultAction(QAction *action)
使用setDefaultAction()函数为一个QToolButton按钮设置一个Action之后,将自动获取Action的文字、图标、ToolTip等设置为按钮的相应属性。所以,在界面设计时无需为QToolButton做过多的设置。
在主窗体类里定义一个私有函数setActionsForButton(),用来为界面上的QToolButton按钮设置关联的Actions,setActionsForButton()在主窗口的构造函数里调用,其代码如下:
void MainWindow::setActionsForButton()
{//为QToolButton按钮设置Action
ui->tBtnListIni->setDefaultAction(ui->actListIni);
ui->tBtnListClear->setDefaultAction(ui->actListClear);
ui->tBtnListInsert->setDefaultAction(ui->actListInsert);
ui->tBtnListAppend->setDefaultAction(ui->actListAppend);
ui->tBtnListDelete->setDefaultAction(ui->actListDelete);
ui->tBtnSelALL->setDefaultAction(ui->actSelALL);
ui->tBtnSelNone->setDefaultAction(ui->actSelNone);
ui->tBtnSelInvs->setDefaultAction(ui->actSelInvs);
}
在程序启动后,界面上的ToolButton按钮自动根据关联的Actions设置其按钮文字、图标和ToolTip。单击某个ToolButton按钮,就是执行了其关联的Action的槽函数代码。使用Actions集中设计功能代码,用于菜单、工具栏、ToolButton的设计,是避免重复编写代码的一种方式。
2.为QToolButton按钮设计下拉菜单
还可以为QToolButton按钮设计下拉菜单,单击工具栏上的“项选择”按钮,会在按钮的下方弹出一个菜单,有3个菜单项用于项选择。
在主窗口类里定义一个私有函数createSelectionPopMenu(),并在窗口的构造函数里调用,其代码如下:
void MainWindow::createSelectionPopMenu()
{//创建下拉菜单
QMenu* menuSelection=new QMenu(this); //创建弹出式菜单
menuSelection->addAction(ui->actSelALL);
menuSelection->addAction(ui->actSelNone);
menuSelection->addAction(ui->actSelInvs);
//listWidget上方的tBtnSelectItem按钮
ui->tBtnSelectItem->setPopupMode(QToolButton::MenuButtonPopup);
ui->tBtnSelectItem->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
ui->tBtnSelectItem->setDefaultAction(ui->actSelPopMenu);//关联Action
ui->tBtnSelectItem->setMenu(menuSelection); //设置下拉菜单
//工具栏上的 下拉式菜单按钮
QToolButton *aBtn=new QToolButton(this);
aBtn->setPopupMode(QToolButton::InstantPopup);
aBtn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);//按钮样式
aBtn->setDefaultAction(ui->actSelPopMenu);
aBtn->setMenu(menuSelection);//设置下拉菜单
ui->mainToolBar->addWidget(aBtn); //工具栏添加按钮
//工具栏添加分隔条,和"退出"按钮
ui->mainToolBar->addSeparator();
ui->mainToolBar->addAction(ui->actQuit);
}
这段代码首先创建一个QMenu对象menuSelection,将3个用于选择列表项的Action添加作为菜单项。
tBtnSelectItem是窗体上ListWidget上方具有下拉菜单的QToolButton按钮的名称,调用了QToolButton类的4个函数对其进行设置。
setPopupMode(QToolButton::MenuButtonPopup):
设置其弹出菜单的模式。QToolButton:: MenuButtonPopup是一个枚举常量,这种模式下,按钮右侧有一个向下的小箭头,必须单击这个小按钮才会弹出下拉菜单,直接单击按钮会执行按钮关联的Action,而不会弹出下拉菜单。
setToolButtonStyle(Qt::ToolButtonTextBesideIcon):
设置按钮样式,按钮标题文字在图标右侧显示。
setDefaultAction(ui->actSelPopMenu):
设置按钮的关联Action,actSelPopMenu与actSelInvs有信号与槽的关联,所以,直接单击按钮会执行“反选”的功能。
setMenu(menuSelection):
为按钮设置下拉菜单对象。
工具栏上具有下拉菜单的按钮需要动态创建。先创建QToolButton对象aBtn,同样用以上4个函数进行设置,但是设置的参数稍微不同,特别是设置弹出菜单模式为:
aBtn->setPopupMode(QToolButton::InstantPopup)
//这种模式下,工具按钮的右下角显示一个小的箭头,单击按钮直接弹出下拉菜单,
//即使为这个按钮设置了关联的Action,也不会执行Action的功能。这是这两个具有
//下拉菜单的QToolButton按钮的区别。
setActionsForButton()和createSelectionPopMenu()函数在窗口的构造函数里调用,构造函数的完整代码如下:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setCentralWidget(ui->splitter);
setActionsForButton();
createSelectionPopMenu();
}