# Qt GUI
###### tags: `inbox`|`Qt5(C++)`
[TOC]
## At the Beginning of a Project
We have four tools. CentralWiget which is locked, menuBar on the top, mainToolBar,and statusBar at below.

## Layouts
### Vertical Layout
+ 物件是很多個row的

### Horizontal Layout
+ 物件是很多個column的

### Grid Layout
+ 物件排列成格子狀

### Form Layout

## Spacers
用於填充空白
### Horizontal Spacer

### Vertical Spacer

## Buttons
##### [What is the different between QPushButton and QToolButton?](https://hackmd.io/@YunTseng/Qt5ButtonsProblem_1)
### Push Button
+ 特性:
+ QPushButton is more for "Ok"/"Close" type buttons that contain text with an optional icon.
+ should always have text.
### Tool Button
+ 特性:
+ 有圖標顯示圖標(文本默認不顯示),無圖標則顯示文本
+ A tool button is meant to be displayed in a grid
+ it has smaller default internal margins than a push button.
+ should generally have an icon.
### Radio Button
+ use QButtonGroup to make it work as radio button

```
likebtn = new QButtonGroup;
likebtn->addButton(ui->rbApple,0);
likebtn->addButton(ui->rbBanana,1);
likebtn->addButton(ui->rbCat,2);
connect(ui->rbApple,SIGNAL(clicked()),this,SLOT(gbLike_clicked()));
connect(ui->rbBanana,SIGNAL(clicked()),this,SLOT(gbLike_clicked()));
connect(ui->rbCat,SIGNAL(clicked()),this,SLOT(gbLike_clicked()));
```
### Check Box

+ when it click, it means yes, otherwise is no.
> 寫一個yes的check box 又寫一個no的check box => 錯!
### Command Link Button
+ QCommandLinkButton繼承自QPushButton,是Vista 引入的新控件。
### Dialog Button Box

## Item Views (Model-Based)
### List View
+ if you have two-hundred million elements, then this is a good point to use listview.

:::spoiler code example
```cpp=
void MainWindow::on_aTest3_triggered()
{
QWidget* window = new QWidget; //Create a new window
QVBoxLayout *mainLayout = new QVBoxLayout(window);
window->show();
// Create a new QWidget
widget = new QWidget();
mainLayout->addWidget(widget);
// Create the ListView
QListView * listView = new QListView(widget);
// Create the QStringListModel
QStringListModel * model = new QStringListModel(widget);
QStringList list;
list << "Item 1" << "Item 2" << "Item 3";
model->setStringList(list);
// Set the model for the ListView
listView->setModel(model);
// Create a layout for the QWidget and add the ListView to it
QVBoxLayout *layout = new QVBoxLayout(widget);
layout->addWidget(listView);
// Set the layout for the QWidget
widget->setLayout(layout);
}
```
:::
### Tree View
```Cpp=
#include <QTreeView>
#include <QStandardItemModel>
```
+ It is similar to a QListView in that it displays a list of items, but with the added ability to display items in a hierarchical manner.
+ A QTreeView is useful when you need to display data that has a hierarchical structure, such as a file system or a directory structure.
+ A QTreeView is also useful when you need to display large amounts of data that can be sorted and filtered. Because a QTreeView only displays the items that are visible on the screen, it is more memory efficient than a QListView for displaying large datasets.

:::spoiler code example
```cpp=
void MainWindow::on_aTest4_triggered(){ //autolayout treeview
QWidget* window = new QWidget; //Create a new window
QVBoxLayout *mainLayout = new QVBoxLayout(window);
window->show();
// Create a new QWidget
widget = new QWidget();
mainLayout->addWidget(widget);
// Create the QTreeView
QTreeView *treeView = new QTreeView(widget);
// Create a QStandardItemModel
QStandardItemModel *model = new QStandardItemModel(widget);
// Add some items to the model
QStandardItem *rootItem = model->invisibleRootItem();
QStandardItem *item1 = new QStandardItem("Item 1");
QStandardItem *item1_1 = new QStandardItem("Item 1_1");
QStandardItem *item2 = new QStandardItem("Item 2");
QStandardItem *item3 = new QStandardItem("Item 3");
rootItem->appendRow(item1);
item1->appendRow(item1_1);
rootItem->appendRow(item2);
rootItem->appendRow(item3);
// Set the model for the QTreeView
treeView->setModel(model);
// Create a layout for the QWidget and add the QTreeView to it
QVBoxLayout *layout = new QVBoxLayout(widget);
layout->addWidget(treeView);
// Set the layout for the QWidget
widget->setLayout(layout);
}
```
:::
### Table View
```cpp=
#include <QTableView>
#include <QHeaderView>
```
+ A QTableView is a widget in Qt that is used to display and edit tabular data. It provides a user interface for viewing, editing, and navigating rows and columns of data.
+ QTableView provides many features that make it easy to work with tabular data, including support for sorting, filtering, and selecting rows and columns. It also supports custom styling and theming

:::spoiler code example
```cpp=
void MainWindow::on_aTest5_triggered(){ //autolayout tableview
QWidget* window = new QWidget; //Create a new window
QVBoxLayout *mainLayout = new QVBoxLayout(window);
window->setWindowTitle("tableview");
window->show();
// Create a new QWidget
widget = new QWidget();
mainLayout->addWidget(widget);
// Create a new QTableView
QTableView *tableView = new QTableView(widget);
// Create the model for the table
QStandardItemModel *model = new QStandardItemModel(widget);
// Set the headers for the table
model->setHorizontalHeaderLabels({"Column 1", "Column 2", "Column 3"});
// Populate the table with some data
QList<QStandardItem*> row1 = {new QStandardItem("Data 1"), new QStandardItem("Data 2"), new QStandardItem("Data 3")};
QList<QStandardItem*> row2 = {new QStandardItem("Data 4"), new QStandardItem("Data 5"), new QStandardItem("Data 6")};
model->appendRow(row1);
model->appendRow(row2);
// Set the model for the table
tableView->setModel(model);
// Set the auto-layout for the table
tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
// Create a layout for the QWidget and add the QTreeView to it
QVBoxLayout *layout = new QVBoxLayout(widget);
layout->addWidget(tableView);
// Set the layout for the QWidget
widget->setLayout(layout);
}
```
:::
### Column View
```cpp=
#include <QStandardItemModel>
#include <QColumnView>
```
+ each column represents a level of the hierarchy. The first column represents the root level, the second column represents the children of the selected item in the first column, and so on. The user can select an item in any column, and the children of that item will be displayed in the next column.
+ is useful for displaying structured data, such as file directories, and allows users to easily navigate through the data in a hierarchical manner.
+ It seems that QColumnView only supports displaying a single column of items. If you want to display multiple columns, you can use a QTreeView instead and customize its appearance to look like a column view.

:::spoiler code example: single column
```cpp=
void MainWindow::on_aTest6_triggered()
{
QWidget* window = new QWidget; //Create a new window
QVBoxLayout *mainLayout = new QVBoxLayout(window);
window->setWindowTitle("columnview");
window->show();
// Create a new QWidget
widget = new QWidget();
mainLayout->addWidget(widget);
// Create the column view
QColumnView * columnView = new QColumnView(widget);
QStandardItemModel *m_model = new QStandardItemModel(widget);
columnView->setModel(m_model);
// Create the items for the column view
QList<QStandardItem *> items;
for (int i = 0; i < 5; i++) {
QStandardItem *item = new QStandardItem(QString("Item %1").arg(i+1));
items.append(item);
}
m_model->appendColumn(items);
// Set the layout for the central widget
QVBoxLayout *layout = new QVBoxLayout(widget);
layout->addWidget(columnView);
// Set the title of the main window
setWindowTitle("Column View Example");
}
```
:::
:::spoiler code example three columns (treeview instead)
```cpp=
void MainWindow::on_aTest6_triggered() //three columns view
{
QWidget* window = new QWidget; //Create a new window
QVBoxLayout *mainLayout = new QVBoxLayout(window);
window->setWindowTitle("columnview");
window->show();
// Create a new QWidget
widget = new QWidget();
mainLayout->addWidget(widget);
// Create the tree view
QTreeView * treeView = new QTreeView(widget);
QStandardItemModel *m_model = new QStandardItemModel(widget);
treeView->setModel(m_model);
// Set header labels
m_model->setHorizontalHeaderLabels(QStringList() << "Column 1" << "Column 2" << "Column 3");
// Create the items for the tree view
QList<QStandardItem *> items;
for (int i = 0; i < 5; i++) {
QList<QStandardItem *> rowItems;
for (int j = 0; j < 3; j++) {
QStandardItem *item = new QStandardItem(QString("Item %1,%2").arg(i+1).arg(j+1));
rowItems.append(item);
}
m_model->appendRow(rowItems);
}
// Resize the columns to fit the contents
treeView->resizeColumnToContents(0);
treeView->resizeColumnToContents(1);
treeView->resizeColumnToContents(2);
// Set the layout for the central widget
QVBoxLayout *layout = new QVBoxLayout(widget);
layout->addWidget(treeView);
}
```
:::
### Undo View
```cpp=
#include <QUndoView>
#include <QUndoStack>
```
+ You can use the QUndoView widget to display the undo and redo actions and allow the user to navigate through the undo and redo history.
+ QUndoView provides an interface for viewing the undo stack and allows the user to navigate the undo and redo history of the stack. It displays a list of the actions that can be undone and redone, along with the current state of the stack. The user can select an action to undo or redo by clicking on it, and can also customize the appearance of the view.
pic
:::spoiler code example
```cpp=
```
:::
## Item Widgts (Item-Based)
### List Widget
+ The QListWidget can be used to create simple list views, or it can be customized to display complex items with custom widgets. It also provides support for drag and drop operations, editing of items, and sorting.
+ Common use:
+ Displaying a list of items that can be selected by the user
+ Displaying a list of items with associated icons or images
+ Creating a simple file or directory browser
+ Implementing a basic chat or messaging interface

:::spoiler example code
```cpp=
void MainWindow::on_pbLW_clicked() //list Widget
{
QListWidget * listWidget = new QListWidget(this);
QStringList items = {"Item 1", "Item 2", "Item 3"};
listWidget->addItems(items);
setCentralWidget(listWidget);
}
```
:::
### Tree Widget
### Table Widget
## Containers
### Group Box
### Scroll Box
### Tool Box
### Tab Widget
### Stacked Widget
### Frame
### Widget
### MDI Area
### Dock Widget
## Input Widgets
### Combo Box
+ multiple choice, get current text:
+ `QString str = ui->comboBox->currentText();`
+ see if it's necessary to use slot.
### Font Combo Box
### Line Edit
+ gettext: `text()`
+ settext: `setText(text)`
+ one line only
### Text Edit
+ gettext: `toPlainText()`
+ settext: `setText(text)`
+ multiple lines
+ can display images in QTextEdit
+ use `<img>` to do it
+ if use `pixmap` then use label to do it.
+ can't adjust the size of images!
+ these work.
```
QString path = QApplication::applicationDirPath();//Debug build file
QString likes = ui->teLikeout->toPlainText();
path = path + "\\image\\" + likes + ".jpg";
QString filename = ui->leNameout->text() + " likes " + ui->teLikeout->toHtml() + "<img src = \"" + path +"\" alt = \"\"/>";
ui->teLikeimg->setHtml(filename);
```
### Plain Text Edit
+ gettext: `toPlainText()`
+ settext: `setPlainText(text)`
+ QPlainTextEdit works on paragraphs and characters.
+ Qt5's documentation doesn't mention that QPlainTextEdit has setText(QString) like QTextEdit does.
### Spin Box
### Double Spin Box
### Time Edit
### Date Edit
### Date/Time Edit
### Dial
### Horizontal Scroll Bar
### Vertical Scroll Bar
### Horizontal Slider
### Vertical Slider
### Key Sequence Edit
## Display Widgets
### Label
+ label is a show text
+ QLabel 自己適應 text 的大小 ```LabelName->adjustSize();```
+ 讓QLabel能夠自動判斷並換行顯示:
```
LabelName->setGeometry(QRect(328, 240, 329, 27*4)); //四倍行距
LabelName->setWordWrap(true);
LabelName->setAlignment(Qt::AlignTop);
```
### Text Browser
### Graphics View
### Calendar Widget
### LCD Number
### Progress Bar
### Horizontal Line
### Vertical Line
### OpenGL Widget
### QQuickWidget
### QWebView