# QWidget
QWidget
类是所有窗口类的父类
(控件类也属于窗口类
),QWidget 类的父类的 QObject 也意味着所有窗口类对象只要指定了父对象,都可以实现内存资源的自动回收
。
# 常见
QWidget
QDialog
QMessageBox 信息窗口
QFileFialog 选择文件
QFontDialog 设置文字
QColor 设置颜色
QInputDialog 设置对话框
QPrgressDialog 进度条
浮动窗口
# 代码
实现 记忆
# mainwindow
//mainwindow.cpp | |
#include "mainwindow.h" | |
#include <QMessageBox> | |
#include "ui_mainwindow.h" | |
#include <QDebug> | |
#include "mydialog.h" | |
#include <QFileDialog> | |
#include <QFontDialog> | |
#include <QColorDialog> | |
#include <QPainter> | |
#include <QInputDialog> | |
#include <QProgressDialog> | |
#include <QTimer> | |
MainWindow::MainWindow(QWidget *parent) : | |
QMainWindow(parent), | |
ui(new Ui::MainWindow) | |
{ | |
ui->setupUi(this); | |
// 设置窗口最大尺寸,不计算标题栏 | |
//setMaximumSize(600,600); | |
// 设置窗口最小尺寸 | |
//setMinimumSize(300,300); | |
// 设置窗口固定尺寸 | |
//setFixedSize(300,300); | |
// 设置窗口标题 | |
setWindowTitle("QWidget"); | |
// 给显示的窗口设置图标 | |
setWindowIcon(QIcon("e:\\ico.png")); | |
// 当用户修改图标之后,connect 对信号进行处理,title 是 window 改变之后,会传递的 titile | |
connect(this,&MainWindow::windowTitleChanged,this,[](const QString &title){ | |
qDebug()<<"新的标题"<<title; | |
}); | |
// 当用户修改图标之后,connect 对信号进行处理,title 是 window 改变之后,会传递的 titile | |
connect(this,&MainWindow::windowIconChanged,this,[](const QIcon &icon){ | |
qDebug()<<"图标被改变"; | |
}); | |
// 设置窗口右键菜单 | |
// 设置右键菜单策略 | |
setContextMenuPolicy(Qt::CustomContextMenu);// 点击了窗口之后,会发射一个信号,参数是 CustomContextMenu | |
// 连接一下被点击之后的事件,参数为鼠标按下去的点 | |
connect(this,&MainWindow::customContextMenuRequested,this,[](const QPoint &pos) | |
{ | |
// 创建菜单对象 | |
QMenu menu; | |
// 添加参加项 | |
menu.addAction("西红柿"); | |
menu.addAction("黄瓜"); | |
menu.addAction("茄子"); | |
// 显示菜单,以及显示菜单的位置,即用到上面传递的参数 | |
menu.exec(QCursor::pos()); | |
}); | |
// 添加 connect 操作,当用户点击窗口之后,做出相关的操作 | |
connect(ui->save_action,&QAction::triggered,this,[=]() | |
{ | |
QMessageBox::information(this,"clicked","你不要通过保存文件调戏我..."); | |
}); | |
connect(ui->open_action,&QAction::triggered,this,[=]() | |
{ | |
QMessageBox::information(this,"clicked","你不要通过打开文件调戏我..."); | |
}); | |
// 给当前的工具栏添加按钮和单行的输入框 | |
// 添加输入框 | |
QLineEdit* edit = new QLineEdit; | |
edit->setMaximumWidth(200); // 设置它的最大宽度 | |
ui->toolBar->addWidget(edit); | |
ui->toolBar->addWidget(new QPushButton("搜索")); | |
// 添加第二个工具栏 | |
QToolBar* toolbar = new QToolBar("toolbar"); | |
this->addToolBar(Qt::LeftToolBarArea,toolbar); | |
// 状态栏添加子控件‘ | |
ui->statusBar->showMessage("...........我是状态栏....",3000); // 显示 3 秒 | |
// 按钮 | |
QPushButton* button = new QPushButton("按钮"); | |
ui->statusBar->addWidget(button); | |
// 标签 | |
QLabel* label = new QLabel("hello word"); | |
ui->statusBar->addWidget(label); | |
// 也可在状态栏显示对应的文本信息,会和上面的信息叠加,若放到上面会覆盖创建的 | |
//ui->statusBar->showMessage ("........... 我是状态栏...."); | |
// 根据时间让我是状态栏关闭,然后显示出按钮和 label | |
QTimer::singleShot(5000,this,[=]() //5 秒之后再显示出来 | |
{ | |
button->show(); | |
label->show(); | |
}); | |
} | |
MainWindow::~MainWindow() | |
{ | |
delete ui; | |
} | |
void MainWindow::on_moverButtion_clicked() | |
{ | |
// 得到左上角的坐标 | |
QRect rect = this->frameGeometry(); | |
// 移动窗口,从当前的左上角左面,移动 x 右 10,y 下 20 | |
move(rect.topLeft()+QPoint(10,20)); | |
} | |
void MainWindow::on_positionButton_clicked() | |
{ | |
// 获取当前窗体的位置信息 | |
QRect rect = this->frameGeometry(); | |
qDebug() <<"左上角"<<rect.topLeft() | |
<< "右上角: " << rect.topRight() | |
<< "左下角: " << rect.bottomLeft() | |
<< "右下角: " << rect.bottomRight() | |
<< "宽度: " << rect.width() | |
<< "高度: " << rect.height(); | |
} | |
void MainWindow::on_geometryButton_clicked() | |
{ | |
int x = 100 + rand() % 500; | |
int y = 100 + rand() % 500; | |
int width= this->width()+10; | |
int height = this->height()+10; | |
// 设置当前窗口的位置以及长度和宽度 | |
setGeometry(x,y,width,height); | |
} | |
void MainWindow::on_modifbtn_clicked() | |
{ | |
// 修改图标 | |
setWindowTitle("你好,世界"); | |
// 修改图标 | |
setWindowIcon(QIcon("e:\\avatar.jpg")); | |
} | |
// 点击窗体显示 mydialog 的模块对话框 | |
void MainWindow::on_modelDlg_clicked() | |
{ | |
// 顶级对话框 | |
MyDialog dlg; | |
connect(&dlg,&MyDialog::finished,this,[=](int res) //finish 会传递一个 int 值 | |
{ | |
qDebug()<<"result"<<res; | |
}); | |
connect(&dlg,&MyDialog::accepted,this,[=]() //finish 会传递一个 int 值 | |
{ | |
qDebug()<<"accepted 信号被发射..."; | |
}); | |
connect(&dlg,&MyDialog::rejected,this,[=]() //finish 会传递一个 int 值 | |
{ | |
qDebug()<<"rejected 信号被发射..."; | |
}); | |
int ret = dlg.exec(); | |
// 根据不同点击,传递的不同值 | |
if(ret == QDialog::Accepted) | |
{ | |
qDebug()<<"accept button clicked ..."; | |
} | |
else if (ret == QDialog::Rejected) { | |
qDebug()<<"reject button clicked ..."; | |
} | |
else { | |
qDebug()<<"done button clicked"; | |
} | |
} | |
void MainWindow::on_msgbox_clicked() | |
{ | |
QMessageBox::about(this, "about", "这是一个简单的消息提示框!!!"); | |
QMessageBox::critical(this, "critical", "这是一个错误对话框-critical..."); | |
int ret = QMessageBox::question(this, "question", | |
"你要保存修改的文件内容吗???", | |
QMessageBox::Save|QMessageBox::Cancel, | |
QMessageBox::Cancel); | |
if(ret == QMessageBox::Save) // 根据不同的点击值,返回不同的值 | |
{ | |
QMessageBox::information(this, "information", "恭喜你保存成功了, o(* ̄︶ ̄*)o!!!"); | |
} | |
else if(ret == QMessageBox::Cancel) | |
{ | |
QMessageBox::warning(this, "warning", "你放弃了保存, ┭┮﹏┭┮ !!!"); | |
} | |
} | |
// 获取文件 | |
void MainWindow::on_QFiledialogbtn_clicked() | |
{ | |
// 打开已经存在的目录,e:\\temp" 起始 | |
QString dirName = QFileDialog::getExistingDirectory(this, "打开目录", "e:\\"); | |
QMessageBox::information(this, "打开目录", "您选择的目录是: " + dirName); | |
// 打开 txt 文件 | |
// QString arg("Text files (*.txt)"); | |
// QString fileName = QFileDialog::getOpenFileName( | |
// this, "Open File", "e:\\temp", | |
// "Images (*.png *.jpg);;Text files (*.txt)", &arg); | |
// QMessageBox::information (this, "打开文件", "您选择的文件是:" + fileName); | |
// 打开多个本地文件 | |
// QStringList fileNames = QFileDialog::getOpenFileNames( | |
// this, "Open File", "e:\\temp", | |
// "Images (*.png *.jpg);;Text files (*.txt)"); | |
// QString names; | |
// for(int i=0; i<fileNames.size(); ++i) | |
// { | |
// names += fileNames.at(i) + " "; | |
// } | |
// QMessageBox::information (this, "打开文件 (s)", "您选择的文件是:" + names); | |
// 打开保存文件对话框,将文件报错到选中的文件中 | |
//QString fileName = QFileDialog::getSaveFileName (this, "保存文件", "e:\\temp"); | |
//QMessageBox::information (this, "保存文件", "您指定的保存数据的文件是:" + fileName); | |
} | |
void MainWindow::on_fontdlg_clicked() | |
{ | |
// 弹出字体对话框 | |
#if 1 | |
// 方式 1 | |
bool ok; // 变量传参, //ok 为返回值,修改后,为 True | |
// 初始化字体,默认字体,我们可以自己修改 | |
//this 父对象 | |
// | |
QFont ft = QFontDialog::getFont( | |
&ok, QFont("微软雅黑", 12, QFont::Bold), this, "选择字体"); | |
qDebug() << "ok value is: " << ok; | |
#else | |
// 方式 2 | |
QFont ft = QFontDialog::getFont(NULL); | |
#endif | |
// 将选择的字体设置给当前窗口对象 | |
// 将 设置的字体应用到选定的 ui 对象上 | |
ui->fontlabel->setFont(ft); | |
// 设置全局 | |
//this->setFont(ft); | |
} | |
// 设置当颜色点击后 | |
void MainWindow::on_colordlg_clicked() | |
{ | |
// 调用 QColor 的静态函数,参数有默认值 | |
QColor color = QColorDialog::getColor(); | |
//Qt 绘图操作 | |
QBrush brush(color); | |
QRect rect(0, 0, ui->color->width(), ui->color->height()); | |
QPixmap pix(rect.width(), rect.height()); | |
QPainter p(&pix); | |
p.fillRect(rect, brush); | |
ui->color->setPixmap(pix); | |
QString text = QString("red: %1, green: %2, blue: %3, 透明度: %4") | |
.arg(color.red()).arg(color.green()).arg(color.blue()).arg(color.alpha()); | |
ui->colorlabel->setText(text); | |
} | |
// 点击进入输入框 | |
void MainWindow::on_inputdlg_clicked() | |
{ | |
//getInt | |
// 年龄标题 | |
// 你的当前年龄:窗口信息 | |
//10 为默认整形数 | |
//1 为最小值,100 为最大值,2 为步长 | |
// int ret = QInputDialog::getInt (this, "年龄", "您的当前年龄:", 10, 1, 100, 2); | |
// QMessageBox::information (this, "年龄", "您的当前年龄:" + QString::number (ret)); | |
//getDouble 2 为精度,还有个步长的重载 | |
// double ret = QInputDialog::getDouble (this, "工资", "您的工资:", 2000, 1000, 6000, 2); | |
// QMessageBox::information (this, "工资", "您的当前工资:" + QString::number (ret)); | |
//getItem | |
// QStringList items; // 字符串列表,动态 字符串数组 | |
// items << "苹果" << "橙子" << "橘子" << "葡萄" << "香蕉" << "哈密瓜"; | |
// //items 指定下拉选择框,1 默认选择第一个 (QStringList 以 0 开始),false 为数据不可修改,true 数据可以修改 | |
// QString item = QInputDialog::getItem (this, "请选择你喜欢的水果", "你最喜欢的水果:", items, 1, false); | |
// QMessageBox::information (this, "水果", "您最喜欢的水果是:" + item); | |
//password 以密码的形式输入时显示小圆点 | |
// QString text = QInputDialog::getText (this,"密码","请输入密码",QLineEdit::Password,"helloword"); | |
// QMessageBox::information (this, "密码", "您输入的密码是:" + text); | |
// 输入多行信息 | |
QString info = QInputDialog::getMultiLineText(this, "表白", "您最想对漂亮小姐姐说什么呢?", "呦吼吼..."); | |
QMessageBox::information(this, "知心姐姐", "您最想对小姐姐说: " + info); | |
} | |
// 设置进度条 | |
void MainWindow::on_processdlg_clicked() | |
{ | |
//1, 创建进度条的对话框窗口对象 | |
//this 当前窗口的父对象初始化和现实窗口 | |
QProgressDialog* progress = new QProgressDialog( | |
"正在拷贝数据....","取消拷贝",0,100,this); | |
//2, 初始化并显示进度条窗口 | |
progress->setWindowTitle("请稍后..."); | |
// 设置模态显示,在显示进度条时,是否可以点击主窗口 | |
// 在显示进度条窗口时,不可以控制主窗口 | |
progress->setWindowModality(Qt::WindowModal); | |
//3,展示当前窗口 | |
progress->show(); | |
//4,更新进度条 | |
QTimer* timer = new QTimer(this); | |
static int value =0; | |
connect(timer,&QTimer::timeout,this,[=]() | |
{ | |
progress->setValue(value); | |
value++; | |
if(value > progress->maximum()) | |
{ | |
timer->stop(); | |
value = 0; | |
} | |
}); | |
// 当进度条点击取消之后,取消时间进程以及进度条 | |
connect(progress, &QProgressDialog::canceled, this, [=]() | |
{ | |
timer->stop(); | |
value = 0; | |
delete progress; | |
delete timer; | |
}); | |
timer->start(50); | |
// 进度条每隔 50 毫秒更新一次 | |
} |
# mydialog
#include "mydialog.h" | |
#include "ui_mydialog.h" | |
MyDialog::MyDialog(QWidget *parent) : | |
QDialog(parent), | |
ui(new Ui::MyDialog) | |
{ | |
ui->setupUi(this); | |
} | |
MyDialog::~MyDialog() | |
{ | |
delete ui; | |
} | |
void MyDialog::on_AcceptBtn_clicked() | |
{ | |
// 解除当前模态对话框的阻塞,隐藏当前窗口 | |
this->accept(); | |
} | |
void MyDialog::on_RejectBtn_clicked() | |
{ | |
// 解除当前模态对话框的阻塞,隐藏当前窗口 | |
this->reject(); | |
} | |
void MyDialog::on_DoneBtn_clicked() | |
{ | |
// 关闭窗口,其值可以指定 | |
this->done(10);// 此值为 finished 的返回值,一一对应 | |
} |
# 控件
控件仅需记住类名,查询帮助文档即可,优先看帮助文档中控件对应的信号槽,其次公共成员函数
# 按钮
- QPushButton - 普通按钮
- QToolButton - 普通按钮
- QRadioButton -
单选
按钮(一般成组使用) - QCheckBox -- 带
复选框
的按钮
# 练习学习
# UI
# mainwindow.h
#ifndef MAINWINDOW_H | |
#define MAINWINDOW_H | |
#include <QMainWindow> | |
namespace Ui { | |
class MainWindow; | |
} | |
class MainWindow : public QMainWindow | |
{ | |
Q_OBJECT | |
public: | |
explicit MainWindow(QWidget *parent = nullptr); | |
~MainWindow(); | |
private slots: | |
void on_radioButton_13_clicked(); | |
void on_radioButton_11_clicked(); | |
void on_radioButton_12_clicked(); | |
void on_radioButton_10_clicked(); | |
void on_checkBox_14_stateChanged(int arg1); | |
void on_checkBox_5_stateChanged(int arg1); | |
void on_checkBox_6_stateChanged(int arg1); | |
void on_checkBox_7_stateChanged(int arg1); | |
// 添加槽函数,处理复选框按钮状态变化 | |
void statusChanged(int state); | |
private: | |
Ui::MainWindow *ui; | |
int m_number = 0; // 添加一个计数器,记录有几个子节点被选中了 | |
}; | |
#endif // MAINWINDOW_H |
# mainwindow.cpp
#include "mainwindow.h" | |
#include "ui_mainwindow.h" | |
#include <QDebug> | |
MainWindow::MainWindow(QWidget *parent) : | |
QMainWindow(parent), | |
ui(new Ui::MainWindow) | |
{ | |
ui->setupUi(this); | |
// 普通按钮没有 checked 属性 | |
ui->normalBtn->setText("我是屌丝!!"); | |
// 图片路径 | |
ui->normalBtn->setIcon(QIcon(":/avatar.jpg")); | |
ui->normalBtn->setIconSize(QSize(30,30)); | |
connect(ui->normalBtn,&QPushButton::clicked,this,[=]() | |
{ | |
qDebug()<<"我是一个屌丝!!"; | |
}); | |
// 有 check 属性的按钮 (默认是没有 check 属性的 | |
ui->checkbtn->setCheckable(true); | |
// 当按钮被选中之后 | |
connect(ui->checkbtn,&QPushButton::toggled,this,[=](bool bl) | |
{ | |
qDebug()<<"我是被选中的 屌丝!!当前的状态:"<<bl; | |
}); | |
// 让当前按钮与菜单关联 | |
ui->menuBtn->setText("你喜欢那种女孩?"); | |
QMenu* menu = new QMenu; | |
QAction* act = menu->addAction("可爱的"); | |
menu->addAction("粘人的"); | |
menu->addAction("年轻的"); | |
// 点击当前按钮会生成下拉菜单 | |
ui->menuBtn->setMenu(menu); | |
connect(act,&QAction::triggered,this,[=]() | |
{ | |
qDebug()<<"选中可爱的"; | |
}); | |
QAction* actBtn = new QAction(QIcon(":/avatar.jpg"),"奥利给"); | |
ui->actBtn->setDefaultAction(actBtn);//action 和当前的 actbtn 关联到一起 | |
connect(ui->actBtn,&QToolButton::triggered,this,[=](QAction* act) | |
{ | |
act->setText("我是修改后的..."); | |
act->setIcon(QIcon(":/avatar.jpg")); | |
}); | |
ui->actBtn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);// 文本信息显示到图标的下面 | |
// 在按钮上绘制指向某个方向上的箭头 | |
// 设置箭头的方向 | |
ui->arrowbtn->setArrowType(Qt::UpArrow); | |
// 设置显示的文本信息 (QToolButton 默认是不显示文本信息的) | |
ui->arrowbtn->setText("向上"); | |
// 让其显示文本信息 | |
ui->arrowbtn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); | |
// 对 popemenu 的相关操作 | |
// 默认延时显示 (长点击一会) | |
ui->popmenu->setMenu(menu); // 将上面的 menu 与 popmenu 进行关联 | |
/* | |
弹出菜单的弹出模式是一个枚举类型: QToolButton::ToolButtonPopupMode, 取值如下: | |
- QToolButton::DelayedPopup: | |
- 延时弹出,按压工具按钮一段时间后才能弹出,比如:浏览器的返回按钮 | |
- 长按按钮菜单弹出,但是按钮的 clicked 信号不会被发射 | |
- QToolButton::MenuButtonPopup: | |
- 在这种模式下,工具按钮会显示一个特殊的箭头,表示有菜单。(菜单会单独显示) | |
- 当按下按钮的箭头部分时,将显示菜单。按下按钮部分发射 clicked 信号 | |
- QToolButton::InstantPopup: | |
- 当按下工具按钮时,菜单立即显示出来。 | |
- 在这种模式下,按钮本身的动作不会被触发 (不会发射 clicked 信号 | |
*/ | |
// 设置显示模式 | |
ui->popmenu->setPopupMode(QToolButton::DelayedPopup); // 延时弹出 | |
connect(ui->popmenu,&QToolButton::clicked,this,[=]() | |
{ | |
qDebug()<<"我是popMenu按钮,好痒..."; | |
}); | |
// 设置默认喜欢 C++ 为选中 | |
ui->radioButton_9->setChecked(true); | |
// 设置复选框操作 | |
// 设置根节点的三态属性 | |
ui->wives->setTristate(true); | |
// 处理根节点的鼠标点击事件 | |
connect(ui->wives, &QCheckBox::clicked, this, [=](bool bl) | |
{ | |
if(bl) | |
{ | |
// 子节点全部设置为选中状态 | |
ui->fangyi->setChecked(true); | |
ui->longer->setChecked(true); | |
ui->mujianping->setChecked(true); | |
ui->ake->setChecked(true); | |
} | |
else | |
{ | |
// 子节点全部设置为非选中状态 | |
ui->fangyi->setChecked(false); | |
ui->longer->setChecked(false); | |
ui->mujianping->setChecked(false); | |
ui->ake->setChecked(false); | |
} | |
}); | |
// 处理子节点的状态变化,对应的槽函数相同 | |
connect(ui->fangyi, &QCheckBox::stateChanged, this, &MainWindow::statusChanged); | |
connect(ui->longer, &QCheckBox::stateChanged, this, &MainWindow::statusChanged); | |
connect(ui->mujianping, &QCheckBox::stateChanged, this, &MainWindow::statusChanged); | |
connect(ui->ake, &QCheckBox::stateChanged, this, &MainWindow::statusChanged); | |
} | |
MainWindow::~MainWindow() | |
{ | |
delete ui; | |
} | |
void MainWindow::on_radioButton_13_clicked() | |
{ | |
qDebug() << "C++"; | |
} | |
void MainWindow::on_radioButton_11_clicked() | |
{ | |
qDebug() << "GO"; | |
} | |
void MainWindow::on_radioButton_12_clicked() | |
{ | |
qDebug() << "Python"; | |
} | |
void MainWindow::on_radioButton_10_clicked() | |
{ | |
qDebug() << "Java"; | |
} | |
void MainWindow::on_checkBox_14_stateChanged(int arg1) | |
{ | |
if(arg1==Qt::Checked) | |
{ | |
// | |
qDebug()<<"C++"; | |
} | |
else { | |
qDebug()<<"取消C++"; | |
} | |
} | |
void MainWindow::on_checkBox_5_stateChanged(int arg1) | |
{ | |
if(arg1==Qt::Checked) | |
{ | |
// | |
qDebug()<<"Go"; | |
} | |
else { | |
qDebug()<<"取消Go"; | |
} | |
} | |
void MainWindow::on_checkBox_6_stateChanged(int arg1) | |
{ | |
if(arg1==Qt::Checked) | |
{ | |
// | |
qDebug()<<"Python"; | |
} | |
else{ | |
qDebug()<<"取消Python"; | |
} | |
} | |
void MainWindow::on_checkBox_7_stateChanged(int arg1) | |
{ | |
if(arg1==Qt::Checked) | |
{ | |
// | |
qDebug()<<"Java"; | |
} | |
else { | |
qDebug()<<"取消Java"; | |
} | |
} | |
// 槽函数 | |
void MainWindow::statusChanged(int state) | |
{ | |
if(state == Qt::Checked) | |
{ | |
m_number ++; // 选中一个子节点,计数器加 1 | |
} | |
else | |
{ | |
m_number --; // 取消选中一个子节点,计数器减 1 | |
} | |
// 根据计数器值判断根节点是否需要做状态的更新 | |
if(m_number == 7) | |
{ | |
ui->wives->setCheckState(Qt::Checked); | |
} | |
else if(m_number == 0) | |
{ | |
ui->wives->setCheckState(Qt::Unchecked); | |
} | |
else | |
{ | |
ui->wives->setCheckState(Qt::PartiallyChecked); | |
} | |
} |
# 补充
# 使用函数指针调用函数重载
void print(int a,int b); | |
void print(int a); | |
// 使用函数指针 () 代表参数个数 pt 为调用函数后的函数名称 | |
void(*pt)(int) = print; | |
再使用 pt进行使用,就是调用的print | |
pt(3); |
# 代码实现窗口
- 菜单栏
- 工具栏
- 状态栏 (最下面)
- 浮动窗口
- 中心
#include "mainwindow.h" | |
#include <QMenuBar> | |
#include <QToolBar> | |
#include <QStatusBar> | |
#include <QLabel> | |
#include <QDockWidget> | |
#include <QTextEdit> | |
MainWindow::MainWindow(QWidget *parent) | |
: QMainWindow(parent) | |
{ | |
resize(400, 300); | |
//MenuBa 创建菜单栏 | |
QMenuBar *menubar = new QMenuBar(this); | |
setMenuBar(menubar); // 设置菜单栏 | |
//"文件 (&F)" &F 代表快捷键 | |
QMenu *filename = menubar->addMenu("文件(&F)"); 菜单栏上添加菜单 | |
QMenu *editmenu = menubar->addMenu("编辑(&E)"); | |
QMenu *buildname = menubar->addMenu("构建(&B)"); | |
filename->addAction("新建文件(&N)"); | |
filename->addAction("打开文件(&O)"); | |
filename->addSeparator(); // 添加分隔符 | |
filename->addAction("关闭文件(&C)"); | |
editmenu->addAction("恢复(&U)"); // 在编辑下再创建菜单 | |
buildname->addAction("构建所有项目(&R)"); | |
//ToolBar 工具栏 | |
QToolBar *toolbar = new QToolBar(this); | |
addToolBar(Qt::TopToolBarArea, toolbar); // 设置 toolbar 在窗口的顶部可上下左右四个位置可选 | |
toolbar->addAction("新建"); | |
toolbar->addAction("打开"); | |
toolbar->addSeparator(); | |
toolbar->addAction("关闭"); | |
//StatusBar 状态栏,只能在下边 | |
QStatusBar *stbar = new QStatusBar(this); | |
setStatusBar(stbar); | |
QLabel *label = new QLabel(this); | |
label->setText("状态栏"); | |
stbar->addWidget(label); // 状态栏添加此 label | |
//DockWidget 浮动窗口 | |
QDockWidget *dockwidget = new QDockWidget("小窗口", this); | |
addDockWidget(Qt::LeftDockWidgetArea, dockwidget); // 添加在窗口左面 | |
//Central Widget 中间核心区, | |
QTextEdit *edit = new QTextEdit(this); | |
setCentralWidget(edit); | |
} |
# 窗口添加 ICON
//ui->actionNew->setIcon(QIcon("C:/Qt/images/new.png")); | |
// 添加 Qt 资源文件使用格式 ": + 前缀 + 文件名" | |
ui->actionNew->setIcon(QIcon(":/Image/images/new.png")); | |
//ui->actionOpen->setIcon(QIcon("C:/Qt/images/open.png")); | |
ui->actionOpen->setIcon(QIcon(":/Image/images/open.png")); |
# 模态与释放空间
模态 (必须关闭显示的窗口,才可操作其它窗口)
非模态 (显示窗口后,仍然可以操作其它窗口)
关闭窗口,释放本窗口内存空间:dialog->setAttribute(Qt::WA_DeleteOnClose);
QCoreApplication::processEvents();
内核区去检查有没有其他事情要做
QDialog *dialog = new QDialog(this); | |
dialog->resize(200, 100); | |
//dialog->show (); // 非模态对话框 | |
//dialog->exec (); // 模态对话框 方式 1 | |
dialog->setModal(true); // 模态对话框 方式 2 | |
dialog->show(); | |
// 关闭此窗口对应空间会被释放掉 | |
dialog->setAttribute(Qt::WA_DeleteOnClose); |
# 错误对话框
private: | |
QErrorMessage *errordlg; | |
// 函数实现 | |
// 点击之后显示错误对话框 | |
void MainWindow::on_pushButton_7_clicked() | |
{ | |
// QErrorMessage *errordlg = new QErrorMessage(this); | |
errordlg->setWindowTitle("错误"); | |
errordlg->showMessage("危险"); | |
} |
# 向导对话框
QWizardPage *createPage1(void) | |
{ | |
QWizardPage *page = new QWizardPage; | |
page->setTitle("第一步操作"); | |
return page; | |
} | |
QWizardPage *createPage2(void) | |
{ | |
QWizardPage *page = new QWizardPage; | |
page->setTitle("第二步操作"); | |
return page; | |
} | |
void MainWindow::on_pushButton_8_clicked() | |
{ | |
QWizard wizard(this); | |
wizard.setWindowTitle("向导对话框"); | |
wizard.addPage(createPage1()); // 创建两个向导页面 | |
wizard.addPage(createPage2()); | |
wizard.exec(); | |
} |
# 控件
# Item
Item view
在处理大量数据
时 (数据库操作时)性能
要大
于Item widgets
# list Widget
列表
//list 列表 | |
// 添加 item | |
ui->listWidget->addItem("Hello world"); | |
ui->listWidget->addItem("Good morning"); | |
QListWidgetItem *listitem = new QListWidgetItem("I love you, Rick!"); | |
ui->listWidget->addItem(listitem); | |
listitem->setTextAlignment(Qt::AlignHCenter); // 中间居中 | |
QStringList list2; | |
//list<<str; // 通过操作运算符 & lt;< 将一个 QString 字符串存储到该列表中 | |
list2 << "ABCD" << "EFGH" << "IJKL" << "LMNO"; // 通过重载将数据加入到 list2 中 | |
ui->listWidget_2->addItems(list2); // 通过 QStringList 形式添加 |
# Tree Widget
树形结构
//QStringList list; | |
//list << "Name" << "Address"; | |
//ui->treeWidget->setHeaderLabels(list); | |
// 设置树的头标题 | |
ui->treeWidget->setHeaderLabels(QStringList() << "Name" << "Address"); | |
// 为树添加顶部的栏目 | |
QTreeWidgetItem *treeitem1 = new QTreeWidgetItem(QStringList("Bookmarks Toolbar")); | |
ui->treeWidget->addTopLevelItem(treeitem1); | |
QTreeWidgetItem *treeitem2 = new QTreeWidgetItem(QStringList("Bookmark Menu")); | |
ui->treeWidget->addTopLevelItem(treeitem2); | |
// 为顶部栏目设置图标 | |
treeitem1->setIcon(0, QIcon(":/Images/Image/folder.png")); | |
treeitem2->setIcon(0, QIcon(":/Images/Image/folder.png")); | |
// 为顶部 tree 设置孩子 | |
// 第一个数据为 Name,第二个为 Address | |
QTreeWidgetItem *childitem1 = new QTreeWidgetItem(QStringList() << "QWidget" << "Page10"); | |
treeitem1->addChild(childitem1); // 将此添加到列表当中 | |
QTreeWidgetItem *childitem2 = new QTreeWidgetItem(QStringList() << "QMainWindow" << "Page20"); | |
treeitem1->addChild(childitem2); | |
QTreeWidgetItem *childitem3 = new QTreeWidgetItem(QStringList() << "QPushButton" << "Page30"); | |
treeitem2->addChild(childitem3); | |
QTreeWidgetItem *childitem4 = new QTreeWidgetItem(QStringList() << "QLabel" << "Page40"); | |
treeitem2->addChild(childitem4); |
# Table
ui->tableWidget->setColumnCount(3); // 添加列 | |
ui->tableWidget->setRowCount(3); // 添加行 | |
// 增加顶部标题 | |
ui->tableWidget->setHorizontalHeaderLabels(QStringList() << "name" << "sex" << "age"); | |
//ui->tableWidget->setItem(0, 0, new QTableWidgetItem("Rick")); | |
// 设置信息列表 | |
QStringList NameList; | |
NameList << "Rick" << "Jack" << "Michael"; | |
QStringList SexList; | |
SexList << "Male" << "Male" << "Male"; | |
// 将数据加入到 Table 中 | |
for(int row = 0; row < 3; row++) | |
{ | |
int col = 0; | |
ui->tableWidget->setItem(row, col++, new QTableWidgetItem(NameList[row])); | |
ui->tableWidget->setItem(row, col++, new QTableWidgetItem(SexList[row])); | |
ui->tableWidget->setItem(row, col, new QTableWidgetItem(QString::number(20))); //int --> string | |
} |
# Input Widgets
comboBox
下拉列表
ui->comboBox->addItem("博士"); | |
ui->comboBox->addItem("硕士"); | |
ui->comboBox->addItem("本科"); | |
ui->comboBox->addItem("专科"); | |
ui->comboBox->addItem("高中及以下"); |
Font combox
字体下拉栏Line Edit
一行text Edit
可改变格式Plain Text Edit
:只能写SpinBox
数字增加减少Date Edit
日期Time Edit
事件Date/Time Edit
日期时间
// 获取当前时间 | |
QDateTime curDateTime = QDateTime::currentDateTime(); | |
ui->timeEdit->setTime(curDateTime.time()); | |
ui->dateTimeEdit->setDateTime(curDateTime); |
# Label
// 设置文字 | |
ui->label->setText("I love you Rick!"); | |
// 设置图片,QPixmap | |
ui->label_2->setPixmap(QPixmap(":/Image/Image/1.jpeg")); | |
// 使使用尺寸,覆盖全屏 | |
ui->label_2->setScaledContents(true); | |
// 显示未 gif | |
QMovie *mv = new QMovie(":/Image/Image/2.gif"); | |
// 显示 MV | |
ui->label_3->setMovie(mv); | |
// 适应磁村 | |
ui->label_3->setScaledContents(true); | |
// 呈现图片 | |
mv->start(); |
# 容器
# Group Box
在窗口的左上可添加
文字说明
title
: 组框的标题
Alignment
: 标题的对齐方式,flat
:设置组框的绘制方式checkable
:设置是否可以给组框添加复选框
checked
:设置添加的复选框的 ``选择状态`
# Scroll Area
若
子窗口
的区域超过
了会生成向下/左右的滚动条
- ``widgetResizable
:是否
自动调整 ` 滚动区域内部窗口大小alignment
: 对齐方式
MainWindow::MainWindow(QWidget *parent) | |
: QMainWindow(parent) | |
, ui(new Ui::MainWindow) | |
{ | |
ui->setupUi(this); | |
// 创建一个垂直布局对象 | |
QVBoxLayout* vlayout = new QVBoxLayout; | |
for(int i=0; i<11; ++i) | |
{ | |
// 创建标签对象 | |
QLabel* pic = new QLabel; | |
// 拼接图片在资源文件中的路径 | |
QString name = QString(":/images/%1.png").arg(i+1); | |
// 给标签对象设置显示的图片 | |
pic->setPixmap(QPixmap(name)); | |
// 设置图片在便签内部的对其方式 | |
pic->setAlignment(Qt::AlignHCenter); | |
// 将标签添加到垂直布局中 | |
vlayout->addWidget(pic); | |
} | |
// 创建一个窗口对象 | |
QWidget* wg = new QWidget; | |
// 将垂直布局设置给窗口对象 | |
wg->setLayout(vlayout); | |
// 将带有垂直布局的窗口设置到滚动区域中 | |
ui->scrollArea->setWidget(wg); | |
} |
# Tool Box
工具盒子
,分为很多层
,每一层都对应一个窗口
,通过Page页面
切换不同层的窗口
currentIndex
: 工具向中当前选项卡对应的索引
,从 ``0` 开始currentItemText
:工具箱中当前选项卡上显示的标题
curentItemName
:当前选项卡对应的子窗口的 ``objectName`currentItemIcon
:当前选项卡显示的图标
currentItemToolTi
p:当前选项卡显示的 ``提示信息`tabSpacing
: 工具箱中窗口折叠后,选项卡之间的 ``间隙`
// 信号 | |
// 工具箱中当前显示的选项卡发生变化,该信号被发射,index 为当前显示的新的选项卡的对应的索引 | |
[signal] void QToolBox::currentChanged(int index); | |
// 槽函数 | |
// 通过工具箱中选项卡对应的索引设置当前要显示哪一个选项卡中的子窗口 | |
[slot] void QToolBox::setCurrentIndex(int index); | |
// 通过工具箱中选项卡对应的子窗口对象设置当前要显示哪一个选项卡中的子窗口 | |
[slot] void QToolBox::setCurrentWidget(QWidget *widget); |
# Tab Widget
带标签页的窗口,通过标签 ``切换窗口`
tabPosition
:标签在窗口中的位置tabShape
:标签的形状currentIndedx
: 当前选中的标签对应的索引iconSize
: 标签上显示的图标大小elideMode
: 标签上的文本信息省略方式usersSctollButtons
:标签太多时,是否添加滚动按钮documentMode
:文档模式是否开启,如果开启窗口边框 ``会被去掉`tabsClosable
:标签页上是否添加关闭按钮
movable
: 标签页是够可以移动tabBarAuoHide
: 当标签<2
时,标签栏是否自动隐藏currentTabText
: 当前标签上显示的文本信息currentTabName
:当前标签对应的窗口的 objectNamecurrentTabIcon
:当前标签上显示的图标currentTabToolTip
:当前标签的提示信息
// 信号 | |
// 每当当前页索引改变时,就会发出这个信号。参数是新的当前页索引位置,如果没有新的索引位置,则为 - 1 | |
[signal] void QTabWidget::currentChanged(int index); | |
// 当用户单击索引处的选项卡时,就会发出这个信号。index 指所单击的选项卡,如果光标下没有选项卡,则为 - 1。 | |
[signal] void QTabWidget::tabBarClicked(int index) | |
// 当用户双击索引上的一个选项卡时,就会发出这个信号。 | |
//index 是单击的选项卡的索引,如果光标下没有选项卡,则为 - 1。 | |
[signal] void QTabWidget::tabBarDoubleClicked(int index); | |
// 此信号在单击选项卡上的 close 按钮时发出。索引是应该被删除的索引。 | |
[signal] void QTabWidget::tabCloseRequested(int index); | |
// 槽函数 | |
// 设置当前窗口中显示选项卡 index 位置对应的标签页内容 | |
[slot] void QTabWidget::setCurrentIndex(int index); | |
// 设置当前窗口中显示选项卡中子窗口 widget 中的内容 | |
[slot] void QTabWidget::setCurrentWidget(QWidget *widget); |
// mainwindow.cpp | |
MainWindow::MainWindow(QWidget *parent) | |
: QMainWindow(parent) | |
, ui(new Ui::MainWindow) | |
{ | |
ui->setupUi(this); | |
// 点击了标签上的关闭按钮 | |
connect(ui->tabWidget, &QTabWidget::tabCloseRequested, this, [=](int index) | |
{ | |
// 保存信息 | |
// 将点击关闭的 tabwidget 以及标题保存到 enqueue 队列当中,方便添加时调用 | |
QWidget* wg = ui->tabWidget->widget(index); | |
QString title = ui->tabWidget->tabText(index); | |
m_widgets.enqueue(wg); | |
m_names.enqueue(title); | |
// 移除 tab 页 | |
ui->tabWidget->removeTab(index); | |
// 设置当前窗体可用 | |
ui->addBtn->setEnabled(true); | |
}); | |
// 当标签被点击了之后的处理动作 | |
connect(ui->tabWidget, &QTabWidget::tabBarClicked, this, [=](int index) | |
{ | |
qDebug() << "我被点击了一下, 我的标题是: " << ui->tabWidget->tabText(index); | |
}); | |
// 切换标签之后的处理动作 | |
connect(ui->tabWidget, &QTabWidget::currentChanged, this, [=](int index) | |
{ | |
qDebug() << "当前显示的tab页, 我的标题是: " << ui->tabWidget->tabText(index); | |
}); | |
// 点击添加标签按钮点击之后的处理动作 | |
connect(ui->addBtn, &QPushButton::clicked, this, [=]() | |
{ | |
// 将被删除的标签页添加到窗口中 | |
// 1. 知道窗口对象,窗口的标题 | |
// 2. 知道添加函数 | |
ui->tabWidget->addTab(m_widgets.dequeue(), m_names.dequeue());// 从队列中取出数据 | |
// 如果队列为空 | |
if(m_widgets.empty()) | |
{ | |
// 按钮不可用 | |
ui->addBtn->setDisabled(true); | |
} | |
}); | |
} |
# Stacked Widget
一个栈窗口,也是分为不同页面,但是页面切换需要借助外界的控件进行间接切换栈窗口
# Widget
Qt 最简单的窗口,Frame 内嵌到窗口 里是可以带边框的,而 Widget 是不带边框的
- enabled: 窗口能否使用,关闭窗口就不能使用
- geometry: 当前窗口相当于其父窗口所在的位置和宽度高度
- sizePolicy:当前窗口的尺寸策略(尺寸策略生效,必须父窗口进行布局)
- Fixed : 大小固定,不随父窗口进行变化
- Minimun: 默认最小状态显示,父窗口变化,子窗口也会随着变化
- Maximum:默认以最大状态显示,但也会随着父窗口变化而变化
- Perfered: 同时拥有 Minimum 和 Maximum,窗口可以增长和缩放,默认会一一个合适大小显示,默认。
- Expanding: 具有延展属性,可以侵略相邻窗口的空间
- MinimumExpanding : 默认可以延伸,也可以侵略其它窗体控件
- minimumSize:当前窗口的最小尺寸
- maximumSize: 当前窗口的最大尺寸
- sizeIncrement: 当窗口大小发生变化之后,子窗口相对于父窗口位移如何进行计算
- font:窗口字体
- cursor: 当前窗口的光标显示
- mouseTracing:设置窗口是否追踪鼠标移动事件
- TableTracking : 设置窗口是否追踪鼠标移动事件
- focusPolicy:设置窗口焦点策略
- contextMenuPolicy:设置窗口右键菜单策略
- toolTip:鼠标在窗口一定时间,进行提示
- toolTipDuration:设置窗口提示信息持续时长,单位毫秒
- styleSheet : 给窗口设置样式表,进行窗口美化,帮助文档有默认文档
# Frame
Qt 最
简单
的窗口,Frame`` 内嵌到窗口里是可以
带边框的 `,而 Widget 是不带边框的
frameShape
:设置表框的形状
frameshadow
: 窗口阴影形式
QFrame::Plain
:简单的,朴素的, 框架和内容与周围环境显得水平;
使用调色板绘制 QPalette::WindowText 颜色 (没有任何 3D 效果)QFrame::Raised
: 框架和内容出现凸起;使用当前颜色组的明暗颜色绘制 3D 凸起线QFrame::Sunken
: 框架及内容物凹陷;使用当前颜色组的明暗颜色绘制 3D 凹线
lineWidth
: 线条的宽度
,默认值为1
midLineWidth
:设置中线宽度
,主要控制阴影
,默认值为0
# 其它
MDI Area
:``多文档区域容器`Dock Widget
:停靠窗口容器
QAxWidgeet
:Active插件