7. 窗口组件 — [野火]嵌入式Qt应用开发实战指南—基于LubanCat

7. 窗口组件 — [野火]嵌入式Qt应用开发实战指南—基于LubanCat

7.2. QWidget¶

QWidget类是大部分用户界面对象的基类,

我们前面一章节学习了一些基础的控件,大部分都是继承于QWidget类,这里学习下单独作为窗口的QWidget(顶层窗口),以及QWidget类派生的窗口类。

提示

一般而言,当一个组件没有嵌入到其他组件中,则把这个组件叫顶层窗口或者窗口;当一个窗口嵌入到其它窗口中,则它本身的标题栏会隐藏,就叫作控件或者子窗口。

QWidget作窗口时相关的属性:

属性

值/类型

说明

windowFilePath

QString

窗口或者控件的文件路径

windowFlags

Qt::WindowFlags

窗口风格的组合

windowIcon

QIcon

窗口的图标

windowModality

Qt::WindowModality

窗口被模态窗口(当前窗口)给屏蔽了

windowModified

bool

表示窗口中的文档是否被修改

windowOpacity

double

窗口的透明度,取值范围是0~1(默认是1,不透明)

windowTitle

QString

窗口标题文字

窗口的几何图形属性(图片来自于 这):

frameGeometry,frameSize,x,y,pos 是框架的几何区域和大小属性,框架是指窗口的最外层。

geometry,width,height,size,rect 是内部绘图区域的相关属性。

QWidget中定义的信号:

void customContextMenuRequested(const QPoint &pos) // 窗口组件上右击时触发信号,一般用于创建组件的快捷菜单

void windowIconChanged(const QIcon &icon) // 窗口图标改变触发信号

void windowTitleChanged(const QString &title) // 窗口标题改变触发信号

关于Qwidget类的公共函数或者其他属性参考下 这里 或者直接查看Qt Assistant帮助文档。

7.2.1. QFrame¶

QFrame 继承自QWidget,作为有框架的窗口的基类。QFrame类可以直接用于创建没有任何内容的简单占位符框架。

框架样式由框架形状和阴影样式指定,阴影样式用于在视觉上将框架与周围的小部件分开。

这些属性可以使用setFrameStyle()函数一起设置,并可以使用frameStyle()读取。

框架形状为NoFrame,Box,Panel,StyledPanel,HLine和VLine ;

阴影样式为Plain,Raised和Sunken。可以在qframe.h中查看。

qframe.h¶

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15enum Shape {

NoFrame = 0, // no frame

Box = 0x0001, // rectangular box

Panel = 0x0002, // rectangular panel

WinPanel = 0x0003, // rectangular panel (Windows)

HLine = 0x0004, // horizontal line

VLine = 0x0005, // vertical line

StyledPanel = 0x0006 // rectangular panel depending on the GUI style

};

enum Shadow {

Plain = 0x0010, // plain line

Raised = 0x0020, // raised shadow effect

Sunken = 0x0030 // sunken shadow effect

};

我们也可以通过如下两个方法来设置框架阴影和形状。

setFrameShadow(QFrame::Shadow)

setFrameShape(QFrame::Shape)

框架小部件具有描述边框厚度的三个属性:lineWidth,midLineWidth和frameWidth。

lineWidth是框架边框的宽度。可以对其进行修改以自定义框架的外观。

midLineWidt指定了帧中间多余的线的宽度,该线使用第三种颜色来获得特殊的3D效果。请注意,仅针对凸起,凹陷的Box,HLine和VLine框架绘制中线。

frameWidth由框架样式确定,并且frameWidth()函数用于获取为所用样式定义的值。

框架和框架内容之间的边距可以使用QWidget::setContentsMargins()函数自定义。

7.2.2. QGroupBox¶

组合框带标题的组箱形框架。其顶部有一个标题,内部可以容纳各种窗口或控件。

QGroupBox还允许您设置标题(通常在构造函数中设置)和标题的alignment属性来控制标题显示位置。

组合框运行设置checkable来设置组合框中的子窗口是否启用。

您可以通过启用flat属性来最大程度地减少组框的空间消耗,启用此属性会导致删除组合框的左,右和下边缘。

QGroupBox中通常使用QCheckBox或QRadioButton,

使用QRadioButton时候,启用autoExclusive可以实现多个选项的单选效果。

7.2.3. QToolBox¶

QToolBox 类提供一列带标签的窗口,点击标签可以实现窗口收缩切换。

每个标签都带有一个窗口,窗口为QWidget,允许任意添加控件。标签可以设置标签显示文字,Icon以及窗口内容。

QToolBox允许使用addItem()添加标签或使用insertItem()在特定位置插入标签。标签总数由count()获取。

delete()用于删除标签,也可以使用removeItem()从QToolBox中删除标签。

currentIndex()返回QToolBox当前选中的标签索引,使用setCurrentIndex()切换当前选中的标签。

7.2.4. QScrollArea¶

QScrollArea 类提供了另一个窗口小部件的滚动视图。

滚动区域用于显示框架内子窗口小部件的内容。如果窗口小部件超出框架的大小,则视图可以提供滚动条,以便可以查看子窗口小部件的整个区域。

缩放图像时,滚动区域可以提供必要的滚动条:滚动条的外观取决于当前设置的滚动条策略。可以使用QAbstractScrollArea继承的功能来控制滚动条的外观。

7.2.5. QStackedWidget¶

QStackedWidget 类提供了多个Widget堆叠在一起,每个Widget叫做页,每次只能有一个Widget可见。

在QtDesigner中设计的时候,我们可以通过鼠标右键来添加/删除页,每个页可以单独进行UI设计。

我们可以通过currentIndex()和setCurrentIndex()获取和设置当前页(当前显示Widget)。

在代码中我们还可以通过addWidget()和removeWidget()来新增和删除页。

lubancat_qt_tutorial_code/QtWidget/Control_2/mainwindows.cpp¶

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26//按键控制页面切换

void MainWindow::on_btn_stackedWidget_toggle_clicked()

{

int page=ui->stackedWidget_demo->currentIndex();

if(++page>=ui->stackedWidget_demo->count())

page=0;

ui->stackedWidget_demo->setCurrentIndex(page);

}

//将label插入页

void MainWindow::on_btn_stackedWidget_insert_clicked()

{

QLabel *label= new QLabel();

label->setText(QString("page%1").arg(ui->stackedWidget_demo->count()+1));

label->setAlignment(Qt::AlignCenter);

ui->stackedWidget_demo->addWidget(label);

ui->stackedWidget_demo->setCurrentIndex(ui->stackedWidget_demo->indexOf(label));

}

//删除当前页

void MainWindow::on_btn_stackedWidget_delete_clicked()

{

ui->stackedWidget_demo->removeWidget(ui->stackedWidget_demo->currentWidget());

}

在例程中,有三个按键,我们通过来实现QStackedWidget当前显示窗口的切换以及插入、删除页。

7.2.6. QTabWidget¶

QTabWidget 类提供了一堆标签式的窗口。

默认情况下,标签栏显示在页面区域上方,但是可以使用setTabPosition()来设置标签栏的显示的位置。

每个选项卡都与一个不同的窗口(称为页)相关联。页面区域中仅显示当前页面,其他所有页面均被隐藏。

和QStackedWidget用法差不多,currentIndex()和setCurrentIndex()用来获取和设置当前页面索引。

addTab()和removeTab()用来新增和删除页。

lubancat_qt_tutorial_code/QtWidget/Control_2/mainwindows.cpp¶

1

2

3

4void MainWindow::on_cbox_tabWidget_currentIndexChanged(int index)

{

ui->tabWidget->setTabPosition((QTabWidget::TabPosition)index);

}

例程中,当我们改变下拉选框的选项时标签栏的位置会随之改变。

7.2.7. QListWidget¶

QListWidget 类提供了带有列表项的列表视图窗口。

QListWidget是一个便利类,提供与QListView提供的列表视图类似的列表视图,

但具有用于添加和删除项目的经典基于Item的界面。

QListWidget使用内部模型来管理列表中的每个QListWidgetItem,

QListWidgetItem就是QListWidget中具体某一列。

有两种方式构建QListWidgetItem,

lubancat_qt_tutorial_code/QtWidget/Control_2/mainwindows.cpp¶

1

2

3

4

5

6//方式1,listWidget作为item父窗口

new QListWidgetItem(tr("text"), listWidget);

//方式2,将item插入到listWidget

QListWidgetItem *newItem = new QListWidgetItem;

listWidget->insertItem(row, newItem);

QListWidgetItem 提供 setText(),setCheckState(), setFlags() 等等方法来设置item属性。

标志

描述

Qt::NoItemFlags

0

它没有设置任何属性

Qt::ItemIsSelectable

1

可以选择

Qt::ItemIsEditable

2

可以编辑

Qt::ItemIsDragEnabled

4

可以拖动它

Qt::ItemIsDropEnabled

8

可以用作放置目标

Qt::ItemIsUserCheckable

16

用户可以选中它,也可以不选中它

Qt::ItemIsEnabled

32

用户可以与该项目进行交互

Qt::ItemIsAutoTristate

64

项的状态取决于其子项的状态。这样可以自动管理QTreeWidget中父项的状态(检查是否选中了所有子项;如果选中了所有子项,则不选中;如果仅选中了一些子项,则部分选中)

Qt::ItemIsTristate

ItemIsAutoTristate

此枚举值已弃用。改用Qt :: ItemIsAutoTristate

Qt::ItemNeverHasChildren

128

该物品永远不会有子物品。这仅用于优化目的

Qt::ItemIsUserTristate

256

用户可以在三个单独的状态之间循环。这个值是在Qt 5.5中添加的

例如在例程中,item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled);这个item就能够被点击被选中被编辑。

QListWidget的操作无外乎就是对列表的item进行添加,修改,删除。

添加item可以使用addItem(),insertItem();

删除时需先获取item,然后delete。

修改,currentItem(),setCurrentItem()可以获取当前的列和item的位置,再对item进行修改。同时也可以通过信号和槽,如当前QListWidget中当前item发生改变会产生currentItemChanged()信号,item被点击会产生itemClicked()等信号,通过这些信号我们可以获取受影响的item并进行相关操作。

lubancat_qt_tutorial_code/Control_2/mainwindows.cpp¶

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43void MainWindow::on_btn_listWidget_add_clicked()

{

QListWidgetItem *item=new QListWidgetItem();

item->setText(QString("当前列:%1").arg(ui->listWidget->count()));

if(ui->cbox_listWidget_style->currentText()=="style 1")

{

item->setIcon(QIcon(":/images/ic_hand_30.png"));

}

else if((ui->cbox_listWidget_style->currentText()=="style 2"))

{

item->setCheckState(Qt::Unchecked);

}

else if((ui->cbox_listWidget_style->currentText()=="style 3"))

{

item->setIcon(QIcon(":/images/ic_handle.png"));

item->setCheckState(Qt::Checked);

}

if (ui->cbox_edit->isChecked())

item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled);

else

item->setFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled);

ui->listWidget->addItem(item);

}

void MainWindow::on_btn_listWidget_insert_clicked()

{

QListWidgetItem *item=new QListWidgetItem();

...

ui->listWidget->insertItem(ui->listWidget->currentRow(),item);

}

void MainWindow::on_btn_listWidget_delete_clicked()

{

QListWidgetItem* item=ui->listWidget->takeItem(ui->listWidget->currentRow());

delete item;

}

void MainWindow::on_btn_listWidget_clear_clicked()

{

ui->listWidget->clear();

}

在例程中,演示了列表的添加、插入,删除和清空。

7.2.8. QTreeWidget¶

QTreeWidget 类提供使用预定义树模型的树视图窗口。

QTreeWidget类是一个便利类,它为标准树小部件提供一个经典的基于Item的界面,

此类基于Qt的Model/View体系结构,并使用默认模型来保存Item。

树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可用树形象表示。

树在计算机领域中也得到广泛应用,如在编译源程序如下时,可用树表示源源程序如下的语法结构。

又如在数据库系统中,树型结构也是信息的重要组织形式之一。

一切具有层次关系的问题都可用树来描述。

在不使用Model/View框架的时候,使用QTreeWidget可以很简单的创建树结构的窗口以

一种更灵活的方法涉及将QTreeView与标准项目模型结合在一起。从而实现数据存储和表示相分别。

目录就是一种典型的树结构

提示

点击“选择目录”,尽量选择目录文件较少的目录。

例程中,我们使用QTreeWidget展示某个目录下的所有文件和文件夹

lubancat_qt_tutorial_code/Widget/mainwindows.cpp¶

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57void MainWindow::on_btn_treeWidget_path_clicked()

{

QString curPath=QDir::currentPath();

QString dlgTitle="选择文件夹";

QString rootpath = QFileDialog::getExistingDirectory(this,dlgTitle,curPath);

if (rootpath.isEmpty())

return;

QTreeWidgetItem* root = new QTreeWidgetItem(QStringList()<

root->setIcon(0, QIcon(":/images/notepad/ic_file.png"));

root->setCheckState(1, Qt::Checked);

searchFile(root,rootpath);

ui->treeWidget->addTopLevelItem(root);

}

QFileInfoList MainWindow::searchFile(QTreeWidgetItem *root,QString path)

{

QDir dir(path);

QDir file(path);

file.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);

file.setSorting(QDir::Size | QDir::Reversed);

QFileInfoList fileList = file.entryInfoList();

//当前目录的file

foreach(auto file, fileList)

{

QTreeWidgetItem* child = new QTreeWidgetItem(QStringList()<

child->setIcon(0, QIcon(":/images/notepad/ic_setting.png"));

child->setCheckState(1, Qt::Checked);

root->addChild(child);

}

QFileInfoList fileListCur=dir.entryInfoList(QDir::Files | QDir::Hidden | QDir::NoSymLinks);

QFileInfoList folderList = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);

//当前目录的dir

foreach(auto folder, folderList)

{

QTreeWidgetItem* childroot = new QTreeWidgetItem(QStringList()<

childroot->setIcon(0, QIcon(":/images/notepad/menu_icon.png"));

childroot->setCheckState(1, Qt::Checked);

root->addChild(childroot);

QFileInfoList fileListChild = searchFile(childroot,folder.absoluteFilePath());

fileListCur.append(fileListChild);

fileListCur.append(folder.fileName());

}

return fileListCur;

}

void MainWindow::on_btn_treeWidget_delete_clicked()

{

QTreeWidgetItem* item = ui->treeWidget->currentItem();

delete item;

}

首先选择我们想要展示的目录,定义QTreeWidgetItem来记录目录下的文件和文件夹,

第一步将选择的目录作为根目录, 添加到QTreeWidgetItem中;

然后使用searchFile()遍历该目录,将目录下的文件作为子节点添加到QTreeWidgetItem;

其次遍历文件夹,将文件夹也作为子节点添加到QTreeWidgetItem;

遍历文件夹的时候,递归调用searchFile(),将当前文件夹下一级的文件和文件夹作为次一级的子节点添加到QTreeWidgetItem;

直至我们选择要展示的目录中的所有文件和文件夹都添加到QTreeWidgetItem,再调用addTopLevelItem()

将记录下的所有item显示在QTreeWidget中。

7.2.9. QTableWidget¶

QTableWidget 类提供具有默认模型的基于Item的表视图窗口。

表格小部件为应用程序提供了标准的表格显示工具。QTableWidget中的Item为QTableWidgetItem。

操作QTableWidget表格:

lubancat_qt_tutorial_code/widget/mainwindows.cpp¶

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100// 初始化一个QTableWidget表格,添加行和列

void MainWindow::on_btn_tableWidget_init_clicked()

{

ui->tableWidget->setRowCount(ui->spinBox_row->value());

ui->tableWidget->setColumnCount(ui->spinBox_col->value());

}

// 添加行

void MainWindow::on_btn_tableWidget_addrow_clicked()

{

int curRow=ui->tableWidget->currentRow();

ui->tableWidget->insertRow(curRow);

}

// 添加列

void MainWindow::on_btn_tableWidget_addcol_clicked()

{

int curCol=ui->tableWidget->currentColumn();

ui->tableWidget->insertColumn(curCol);

}

// 删除行

void MainWindow::on_btn_tableWidget_delrow_clicked()

{

int curRow=ui->tableWidget->currentRow();

ui->tableWidget->removeRow(curRow);

}

// 删除列

void MainWindow::on_btn_tableWidget_delcol_clicked()

{

int curCol=ui->tableWidget->currentColumn();

ui->tableWidget->removeColumn(curCol);

}

// 清除表格item

void MainWindow::on_btn_tableWidget_cleartable_clicked()

{

ui->tableWidget->clear();

}

// 清除表格内容

void MainWindow::on_btn_tableWidget_cleardate_clicked()

{

ui->tableWidget->clearContents();

}

// 自动调整行与列

void MainWindow::on_btn_tableWidget_adjust_clicked()

{

ui->tableWidget->resizeColumnsToContents();

ui->tableWidget->resizeRowsToContents();

}

// 在当前选中的表格,插入item

void MainWindow::on_btn_tableWidget_insertitem_clicked()

{

for(int i=0; i< ui->tableWidget->columnCount();i++ )

{

for(int j=0; jtableWidget->rowCount(); j++)

{

QTableWidgetItem *item = new QTableWidgetItem();

item->setText(QString("item(%1,%2)").arg(i+1).arg(j+1));

ui->tableWidget->setItem(i,j,item);

}

}

}

void MainWindow::on_cbox_table_title_clicked(bool checked)

{

ui->tableWidget->verticalHeader()->setVisible(checked); //隐藏列表头

ui->tableWidget->horizontalHeader()->setVisible(checked); //隐藏行表头

}

void MainWindow::on_cbox_tableWidget_EditTrigger_currentIndexChanged(int index)

{

ui->tableWidget->setEditTriggers(QAbstractItemView::EditTrigger(index));

}

void MainWindow::on_cbox_tableWidget_SelectionBehavior_currentIndexChanged(int index)

{

ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectionBehavior(index));

}

void MainWindow::on_cbox_tableWidget_SelectionMode_currentIndexChanged(int index)

{

ui->tableWidget->setSelectionMode(QAbstractItemView::SelectionMode(index));

}

// 显示当前选中的item的行和列

void MainWindow::on_tableWidget_cellClicked(int row, int column)

{

ui->lab_pos_x->setText(QString::number(row+1));

ui->lab_pos_y->setText(QString::number(column+1));

}

// 显示当前点击选中的item的内容

void MainWindow::on_tableWidget_itemClicked(QTableWidgetItem *item)

{

ui->lab_content->setText(item->text());

}

在例程中,实现了一组对QTableWidget的操作,item的插入和清除;

除此以外还有多Item的选择模式,选择行为,item编辑的触发方式进行了设置。

绑定了tableWidget的两个信号,cellClicked(int row, int column)和itemClicked(QTableWidgetItem *item);用来显示当前点击的item序列和item内容。

🖌️ 相关文章

车位价格一般多少钱?一个车位多少钱
365bet体育在线15

车位价格一般多少钱?一个车位多少钱

📅 08-16 👁️ 8231
2022世界杯乌拉圭阵容_2022乌拉圭国家男子足球队主力名单
office365无法打开word

2022世界杯乌拉圭阵容_2022乌拉圭国家男子足球队主力名单

📅 08-29 👁️ 9969
ai拼音的字
365bet代理

ai拼音的字

📅 07-18 👁️ 4657