实例简介
QT中用于项处理的组件有两类:一类是Item Views,包括QListView、QTreeView、QTableView、QColumnView;另一类是Item Widget,包括QListWidget、QTreeWidget、QTableWidget
Item View是基于模型/视图(Model/VIew)结构,视图(View)与模型数据(Model Data)关联实现数据的显示与编辑
Item Widgets是直接将数据储存在每一个项里,一个项储存了文字、文字的格式以及自定义数据
实例效果如下:
实例的功能实现:
-
-
使用QTabWidget设计多页界面,工作区右侧是一个具有三个页面的TabWidget组件
-
使用QToolBox设计多组工具箱,工作区左侧是一个具有三个组的QToolBox组件
-
使用分割条(QSplitter)设计可以左右分割的界面,工作区TabWidget和ToolBox之间有一个splitter,运行时可以分割调整两个组件的大小
-
创建Actions,用Actions设计主工具栏,用Action关联,设计具有下拉功能的ToolButton按钮,在主工具栏上添加具有下拉菜单的ToolButton按钮
-
使用QWidget,演示如何创建和添加项,为项设置图标和复选框,如何遍历列表进行选择
-
QListWidget的主要信号currentItemChanged()的功能,编写响应槽函数
-
为QListWidget组件利用已设计的Actions创建自定义快捷菜单
界面设计
本实例的主窗口从QMainWindow继承而来,采用混合式界面设计。在UI设计界面完成一定的设计,再使用代码对界面进行设计。UI界面设计如下:
此界面的所有按钮都使用QToolButton组件,QToolButton中有一个setDefaultAction()函数,可以使其和一个Action关联,按钮的文字、图标、ToolTip都将自动设置为与其关联的Action一致,单击一个QToolButton就是在执行Action的槽函数,与工具栏上的按钮效果相同。实际上,主工具栏上的按钮就是根据Action自动创建的QToolButton按钮
QToolButton还有一个setMenu()函数,可以为其设置一个下拉式菜单,配合QToolButton的一些属性设置,可以有不同的下拉菜单效果
混合式界面设计中用代码实现的部分,就是为界面上的各ToolButton按钮设置关联的Action,在工具栏上动态添加一个QToolButton,并设置其下拉菜单功能
QToolBox组件的设置
在UI设计界面时,在窗口放置一个QToolBox组件
在ToolBox组件上调出右键快捷菜单,可以使用"Insert Page"、"Delete Page"等菜单项实现分组的添加或删除。单击某个分组的标题,就可以选择为ToolBox组件的当前分组,在Property Editor中主要的属性设置如下:
-
-
currentIndex,当前分组编号,第一个分组的编号是0,通过改变这个值,可以选择不同的分组界面
-
currentItemText,当前分组的标题
-
currentItemName,当前分组的对象名称
-
currentItemIcon,为当前分组设置一个图标,显示在文字标题的左侧
在一个ToolBox内可以放置任何界面组件,如QGroupBox、QLineEdit、QPushButton等。在第一个分组中,放置QToolButton按钮,并设置为Grid布局,注意不能使用水平布局,因为使用水平布局会使得按钮自动向左靠齐,而使用Grid则自动居中
QTabWidget组件设置
QTabWidget是一个多页的容器类组件,在窗口上放置一个QTabWidget组件,通过其快捷菜单中的"Insert Page"和"Delete Page"等菜单项实现页面的添加或删除。在Property Editor中主要的属性设置如下:
-
-
tabPosttion:页标签的位置,东、西、南、北四个方位中进行选择
-
currentIndex:当前页的编号
-
currentTabText:当前页的标题
-
currentTabName:当前页的对象名称
-
currentTabIcon:为当前页设置一个图标,显示在文字左侧
使用QSplitter设计分割界面
具有分割效果的典型界面是Windows的资源管理器,QSplitter用于设计具有分割效果的界面,可以左右分割或上下分割
如果想要将toolBox和tabWidget两个组件设置为左右分割的效果,可以同时选中两个组件,单击主窗口工具栏上的"Lay Out Horizontally in Splitter"按钮,就可以为这两个组件创建一个水平分割的布局组件splitter
在使用分割条调整大小时,如果不希望ToolBox的宽度过小而影响按钮的显示,可以为其设置一个最小宽度(minimumSize.Width)
QLsitWidget的设置
在TabWidget组件的第一个页面上放置一个QListWidget组件,它是一个储存多个项的列表组件,每个项是一个QListWidgetItem类型的对象
双击ListWidget组件,可以打开其列表项编辑器,如下图所示:
在这个编辑器中,可以实现对列表项的增加、删除、上移、下移等操作,也可以设置每个列表项的属性,包括文字、字体格式、背景等多个属性,其中比较重要的是flags属性,用于设置项的一些标记,这些标记是枚举类型Qt::ItemFlag的具体值,包括以下几种:
-
-
Seletcable:项是否可以被选择,对应枚举值Qt::ItemIsSelectable
-
Editable:项是否能被编辑,对应枚举值Qt::ItemIsEditable
-
DragEnable:项是否能被拖动,对应枚举值:Qt::ItemIsDragEnabled
-
DropEnable:项是否能被拖放,对应枚举值:Qt::ItemIsDropEnabled
-
UserChecked:项是否能被复选,如果为true,则项前面出现一个checkBox,对应枚举值Qt::ItemIsUserCheckable
-
Enabled:项是否被使能(和Disable对应)
-
Tristate:是否允许Check的第三种状态,若为false,则只有checked和unChecked两种状态,对应枚举值Qt::ItemIsAtuoTristate
在代码中设置项的flags属性时,使用函数setFlags(),QListWidget的列表项一般是在程序里动态创建
Action的创建
QAciton是Qt的一个类,使用设计的Action可以创建菜单项、工具栏按钮,可以设置为QToolButton按钮关联的Action,点击关联的QToolButton按钮实际执行的就是Action的槽函数
在项目目录树中点击 xxx.ui 文件,进入UI设计器,在窗体下方有一个Action Editor的面板,使用此面板能够对Action进行设计
点击箭头指向的按钮就会新建一个Action,编辑Action的界面如下
点击箭头所指的三角图标,选择Choose File,就能够在本地文件中选择Action的图标,此对话框中的属性如下:
-
-
Text:Action中的显示文字
-
Object name:该Action的Object name
-
ToolTip:当鼠标停留在Action上时出现的提示文字
-
Icon:图标相关设置
-
Checkable:如果选择该选项,Action前会出现一个CheckBox
-
Shortcut:快捷键设置
之后单击OK就会完成Action的创建,成功创建的Action将会以下面的方式保存在Action Editor
如果我们需要使用它们,只需将它们拖拽到指定位置即可
在"Signal &Slots Editor"里设置Action的关联,如下:
QListWidget操作
初始化列表
初始化列表按钮是button按钮,绑定响应单击信号的槽函数内容如下
void MainWindow::on_actInitList_triggered()
{
//初始化列表
QListWidgetItem *aItem; //每一行都是一个QListWidgetItem
QIcon aIcon;
aIcon.addFile("../images/圆.png");
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::Unchecked); //设置为选中状态
ui->listWidget->addItem(aItem); //增加一个项
}
}
列表框中的每一行都是一个项,是一个QListWidget类型的对象,项列表框中添加一个项,就需要创建一个QListWidget类型的实例aItem,然后设置aItem的一些属性,再用addItem函数将aItem添加到列表框中
插入项
插入项使用QListWidget的insertItem(int row,QListWigetItem *item)函数,在某一行row的前面插入一个QListWidgetItem对象item,也需要创建一个item,并为其设置属性。具体代码如下:
void MainWindow::on_actInsertList_triggered()
{
//插入项
QIcon aIcon;
aIcon.addFile("../images/圆.png");
QListWidgetItem* aItem = new QListWidgetItem("New Inserted Item");
aItem->setIcon(aIcon);
aItem->setCheckState(Qt::Unchecked);
ui->listWidget->insertItem(ui->listWidget->currentRow(),aItem);
}
—
删除当前项和清除列表
void MainWindow::on_actClearList_triggered()
{
//清除列表
ui->listWidget->clear();
}
void MainWindow::on_actDeleteList_triggered()
{
//删除当前项
int row = ui->listWidget->currentRow();
//takeItem函数只是移除一个项,并不删除项对象,因此需要使用delete对其进行删除
QListWidgetItem* aItem = ui->listWidget->takeItem(row);
delete aItem;
}
遍历并选择项
界面上有全选和全不选按钮,其具体实现代码如下:
void MainWindow::on_actSelectAll_triggered()
{
//全选
int cnt = ui->listWidget->count();
for (int i=0;i<cnt;i++) {
QListWidgetItem *aItem = ui->listWidget->item(i);
aItem->setCheckState(Qt::Checked);
}
}
void MainWindow::on_actSelectNone_triggered()
{
//全不选
int cnt = ui->listWidget->count();
for (int i=0;i<cnt;i++) {
QListWidgetItem *aItem = ui->listWidget->item(i);
aItem->setCheckState(Qt::Unchecked);
}
}
QListWidget在当前项被切换时会发射两个信号,只是传递的参数不同
-
-
currentRowChanged(int currentRow):传递当前项的行号作为参数
-
currentRowChanged(QListWidgetItem *current,QListWidgetItem *previous):传递两个QListWidgetItem对象作为参数,current表示当前项,previous是前一项
QToolButton与下拉式菜单
QToolButton关联QAction
在此次实例的ToolBox中放置QToolButton的目的是希望它们实现与工具栏上的按钮相同的功能,无需再编写代码,只需设置关联的QAction对象即可
QToolButton有一个函数void QToolButton::setDefaultAction(QAction *action)
使用该函数能够为一个QToolButton按钮设置一个Action之后,将自动获取Action的各种属性,因此在界面设计时无需为QToolButton做过多的设置
在主窗体类中定义一个私有函数setActionForButton(),用来为界面上的QToolButton按钮设置关联的Actions,该函数在主窗口的构造函数中被调用,代码如下:
mainwindow.h中,如下所示:
主窗体的构造函数中,如下所示:
void MainWindow::setActionForButton()
{
//为QToolButton设置Actions
ui->tbtn_Init->setDefaultAction(ui->actInitList);
ui->tbtn_add->setDefaultAction(ui->actAddList);
ui->tbtn_insert->setDefaultAction(ui->actInsertList);
ui->tbtn_delete->setDefaultAction(ui->actDeleteList);
ui->tbtn_clear->setDefaultAction(ui->actClearList);
ui->tBtn_selectItem->setDefaultAction(ui->actSelect);
ui->tBtn_SelAll->setDefaultAction(ui->actSelectAll);
ui->tBtn_SelectNone->setDefaultAction(ui->actSelectNone);
}
程序启动之后,界面上的ToolButton按钮自动根据关联的Actions设置其相关属性。单击QToolButton按钮,就相当于点击工具栏中的响应action
为QToolButton设计下拉菜单
在主窗口类中定义一个私有函数createSelectionPopMenu(),并在窗口的构造函数里调用,具体代码如下:
void MainWindow::createSelectionPopMenu()
{
//创建下拉菜单
QMenu *menuSelection = new QMenu(this); //创建弹出式菜单
menuSelection->addAction(ui->actAddList);
menuSelection->addAction(ui->actInsertList);
//ListWidget上方的QToolButton按钮
ui->tBtn_selectItem->setPopupMode(QToolButton::MenuButtonPopup);
ui->tBtn_selectItem->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
ui->tBtn_selectItem->setDefaultAction(ui->actSelect);
ui->tBtn_selectItem->setMenu(menuSelection); //设置下拉菜单
//工具栏上的下拉菜单按钮
QToolButton *aBtn = new QToolButton(this);
aBtn->setPopupMode(QToolButton::InstantPopup);
aBtn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
aBtn->setDefaultAction(ui->actSelect);
aBtn->setMenu(menuSelection);
ui->toolBar->addWidget(aBtn);
//添加退出按钮
ui->toolBar->addAction(ui->actQuit);
}
效果如下:
在该函数中,首先创建一个QMenu对象,将用于列表项选择的Action添加作为菜单项
tBtn_selectItem是窗体上ListWidget上方具有下拉菜单的QToolButton按钮的名称,调用了四个函数对其属性进行了设置
-
-
setPopupMode(QToolButton::MenuButtonPopup),设置其弹出菜单的模式。QToolButton::MenuButtonPopup是一个枚举常量,这种模式下,按钮右侧有一个向下的小箭头,必须点击这个小箭头才会弹出下拉菜单,直接点击按钮会执行关联的Action,而不会弹出下拉菜单
-
setToolButtonStyle(Qt::ToolButtonTextBesideIcon),设置按钮样式,按钮标题文字在图标的右侧显示(同理将QToolBox中的QToolButton的属性设置为此选项,因为它默认是只显示icon)
-
setDefaultAction(ui->actSelect),将Action关联
-
setMenu(menuSelection),为该按钮设置下拉菜单对象
工具栏上方具有下拉菜单的按钮需要动态创建,单击按钮直接弹出下拉菜单,即使为这个按钮设置了关联的Action,也不会执行Action的功能。这就是两个具有下拉菜单功能的QToolButton按钮的区别
创建右键快捷菜单
每个从QWidget继承的类都会有信号customContextMenuRequested(),这个信号在鼠标右击时发射,为此信号的槽函数,可以创建和运行右键快捷菜单
本实例为listWidget组件的customContextMenuRequested()信号创建槽函数,实现快捷菜单的创建与显示,代码如下:
void MainWindow::on_listWidget_customContextMenuRequested(const QPoint &pos)
{
//为listWidget创建右键快捷菜单
Q_UNUSED(pos);
QMenu* menuList = new QMenu(this);
//添加菜单项
menuList->addAction(ui->actAddList);
menuList->addAction(ui->actInitList);
menuList->addAction(ui->actClearList);
menuList->addAction(ui->actInsertList);
menuList->addAction(ui->actDeleteList);
menuList->addSeparator();
menuList->addAction(ui->actSelectAll);
menuList->addAction(ui->actSelectNone);
//在鼠标光标处显示右键快捷菜单
menuList->exec(QCursor::pos());
delete menuList;
}
效果如下:
在此函数中,首先创建一个QMenu类型的对象,利用QMenu的addAction()方法添加已经设计好的Action作为菜单项,创建完成之后,使用QMenu::exec()函数显示快捷菜单,使用静态函数QCursor::pos()会获取当前鼠标光标的位置
需要注意的是:在编写完响应槽函数之后,需要在主窗口类构造函数中添加右键菜单策略以确保信号能够成功响应
ui->listWidget->setContextMenuPolicy(Qt::CustomContextMenu);