qt:MainWindow
1.菜单栏
menuBar()函数
ui->setupUi(this);
QMenuBar*bar=new QMenuBar();
this->setMenuBar(bar);
}
还有一种在堆上创建的方法
如果是获取到已经存在的 QMenuBar
,那么这里的设置就是自己替换自己,仍然在对象树上
ui->setupUi(this);
QMenuBar*bar=new QMenuBar(this);
this->setMenuBar(bar);
}
但如果勾选了自动生成 ui 文件(Qt 已经给我们生成了一个 QMenuBar),那么上述代码就会引起内存泄漏
程序自己已经创建好了一个 QMenuBar
,当设置新的 QMenuBar
进来时,就会导致旧的 QMenuBar
脱离了 Qt 的对象树,意味着后续就无法对这个对象进行释放了
上述程序如果窗口关闭,对象树释放,此时进程就结束了,自然所有的内存都回收给系统,上述内存泄漏也就不会造成影响。
但是如果上述代码是出现在一个多窗口的程序中,如果涉及到窗口的频繁跳转切换(窗口的频繁创建销毁),上述内存泄漏就会更严重。但是实际上由于现在的计算机内存比较充裕,上述内存泄漏都还好,但还是要求代码写得更规范一些,所以采用下面这种写法
QMenuBar*bar=this->menuBar();
this->setMenuBar(bar);
菜单栏中创建菜单项
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QMenuBar>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QMenuBar*bar=new QMenuBar();
this->setMenuBar(bar);
QMenu *m1=new QMenu("文件");
QMenu*m2=new QMenu("编辑");
QMenu*m3=new QMenu("视图");
bar->addMenu(m1);
bar->addMenu(m2);
bar->addMenu(m3);
QAction*a1=new QAction("新建");
QAction*a2=new QAction("保存");
QAction*a3=new QAction("删除");
m1->addAction(a1);
m1->addAction(a2);
m1->addSeparator();//添加分割线
m1->addAction(a3);
}
MainWindow::~MainWindow()
{
delete ui;
}
添加快捷键的方法
QAction*a1=new QAction("新建(&Q)");
也可以给菜单增加子菜单
QMenuBar*bar=new QMenuBar();
this->setMenuBar(bar);
QMenu *m1=new QMenu("文件");
QMenu*m2=new QMenu("编辑");
QMenu*m3=new QMenu("视图");
bar->addMenu(m1);
bar->addMenu(m2);
bar->addMenu(m3);
QAction*a1=new QAction("新建(&Q)");
QAction*a2=new QAction("保存");
QAction*a3=new QAction("删除");
m1->addAction(a1);
m1->addAction(a2);
m1->addSeparator();//添加分割线
m1->addAction(a3);
QMenu*m4=new QMenu("选择");
m3->addMenu(m4);
也可以使用setIcon的方式为菜单添加图标,但是如果是最高级菜单,则图标会覆盖文字使文字不显示
2.文件读写
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QFileDialog>
#include<QFile>
#include<fstream>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->pushButton,&QPushButton::clicked,this,&MainWindow::save);
connect(ui->pushButton_2,&QPushButton::clicked,this,&MainWindow::load);
}
void MainWindow::save()
{
QFileDialog*dialog=new QFileDialog(this);
QString filename=dialog->getSaveFileName(this,"保存文件","D:/project/");
qDebug()<<"filename"<<filename;
std::ofstream file(filename.toStdString().c_str());
if (!file.is_open()) {
qDebug() << "文件保存失败!";
return;
}
const QString& text = ui->textEdit->toPlainText();
file << text.toStdString();
file.close();
}
void MainWindow::load()
{
QFileDialog* dialog = new QFileDialog(this);
QString fileName = dialog->getOpenFileName(this, "加载文件", "D:/project/");
qDebug() << "fileName: " << fileName;
std::ifstream file(fileName.toStdString().c_str());
if (!file.is_open()) {
qDebug() << "文件加载失败!";
return;
}
std::string content;
std::string line;
while (std::getline(file, line)) {
content += line;
content += "\n";
}
file.close();
QString text = QString::fromStdString(content);
ui->textEdit->setPlainText(text);
}
MainWindow::~MainWindow()
{
delete ui;
}
3.工具栏
QToolBar
QToolBar*q=new QToolBar();
this->addToolBar(q);
搭配一下菜单栏(菜单只有一个,工具栏可以有多个)
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QToolBar>
#include<QMenuBar>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QMenuBar*m1=new QMenuBar();
this->setMenuBar(m1);
QMenu*me1=new QMenu("文件");
m1->addMenu(me1);
QToolBar*q=new QToolBar();
this->addToolBar(q);
QAction*a1=new QAction("保存");
QAction*a2=new QAction("删除");
me1->addAction(a1);
me1->addAction(a2);
q->addAction(a1);
q->addAction(a2);
}
MainWindow::~MainWindow()
{
delete ui;
}
设置停靠位置,默认在上面
Qt::LeftToolBarArea 停靠在左侧
Qt::RightToolBarArea 停靠在右侧
Qt::TopToolBarArea 停靠在顶部
Qt::BottomToolBarArea 停靠在底部
Qt::AllToolBarAreas 以上四个位置都可停靠
或者这样设置
toolBar2->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
在创建工具栏的同时指定其停靠的位置,指的是程序运行时工具栏默认所在的位置;
而使用 setAllowedAreas()
函数 设置停靠位置,指的是工具栏允许其所能停靠的位置。
设置浮动工具栏
QToolBar*q=new QToolBar();
this->addToolBar(q);
QAction*a1=new QAction("保存");
QAction*a2=new QAction("删除");
// me1->addAction(a1);
// me1->addAction(a2);
q->addAction(a1);
q->addAction(a2);
q->setMovable(true);
QToolBar *toolBar = new QToolBar(this);
addToolBar(Qt::LeftToolBarArea, toolBar);
toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
toolBar->setFloatable(false);
toolBar->setMovable(true);
QAction* openAction = new QAction("open", this);
QAction* newAction = new QAction("new", this);
toolBar->addAction(openAction);
toolBar->addSeparator();
toolBar->addAction(newAction);
QPushButton* button = new QPushButton("保存", this);
toolBar->addWidget(button);
浮动,原始为左侧,可以拖到左右侧
4.状态栏
QStatusBar,一般位于主窗口的最底部一个窗口只能有一个,一般有三类消息
实时消息:如当前程序状态
永久消息:如程序版本号,机构名称
进度消息:如进度条提示,百分百提示
状态栏可以有控件,不过会和临时信息位置冲突
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QLabel>
#include<QProgressBar>
#include<QPushButton>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QStatusBar*b=new QStatusBar();
this->setStatusBar(b);
//b->showMessage("这是一个实时状态信息,存在3秒", 3000);
QLabel*l=new QLabel("这是一个永久信息");
b->addWidget(l);
QProgressBar*p=new QProgressBar();
p->setRange(0,100);
p->setValue(50);
b->addWidget(p);
QPushButton*pb=new QPushButton();
b->addWidget(pb);
}
MainWindow::~MainWindow()
{
delete ui;
}
5.浮动窗口
QDockWidget
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QDockWidget>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QDockWidget*d=new QDockWidget();
this->addDockWidget(Qt::LeftDockWidgetArea,d);
d->setWindowTitle("浮动窗口");
}
MainWindow::~MainWindow()
{
delete ui;
}
设置停靠
Qt::LeftDockWidgetArea 停靠在左侧
Qt::RightDockWidgetArea 停靠在右侧
Qt::TopDockWidgetArea 停靠在顶部
Qt::BottomDockWidgetArea 停靠在底部
Qt::AllDockWidgetAreas 以上四个位置都可停靠
方法:不能直接给浮动窗口添加子控件,而是需要创建出一个单独的 QWidget
,把需要添加的控件如布局管理器加入到 QWidget
中,然后再把这个 QWidget 设置到 dockWidget
中。
ui->setupUi(this);
QDockWidget*d=new QDockWidget();
this->addDockWidget(Qt::LeftDockWidgetArea,d);
d->setWindowTitle("浮动窗口");
QWidget *w=new QWidget();
d->setWidget(w);
QVBoxLayout*b=new QVBoxLayout();
w->setLayout(b);
QLabel*l=new QLabel("标签");
d->setWidget(l);
d->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::TopDockWidgetArea);
综合例子:涉及函数 / 方法:**setFeatures()**设置窗体特性:Movable
可移动、Closable
可关闭、Floatable
可浮动
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QDockWidget>
#include<QVBoxLayout>
#include<QLabel>
#include<QTextEdit>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
/* ui->setupUi(this);
QDockWidget*d=new QDockWidget();
this->addDockWidget(Qt::LeftDockWidgetArea,d);
d->setWindowTitle("浮动窗口");
QWidget *w=new QWidget();
d->setWidget(w);
QVBoxLayout*b=new QVBoxLayout();
w->setLayout(b);
QLabel*l=new QLabel("标签");
d->setWidget(l);
d->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::TopDockWidgetArea);*/
QTextEdit *text = new QTextEdit(this);
text->setText(tr("主窗口"));
text->setAlignment(Qt::AlignCenter);
setCentralWidget(text);
QDockWidget *dock = new QDockWidget(tr("窗口一"),this);
dock->setFeatures(QDockWidget::DockWidgetMovable);
dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
QTextEdit *te1 = new QTextEdit(this);
te1->setText(tr("移动窗口"));
dock->setWidget(te1);
addDockWidget(Qt::RightDockWidgetArea,dock);
//停靠窗口2:可关闭、可浮动
dock = new QDockWidget(tr("窗口二"),this);
dock->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable);
dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
QTextEdit *te2 = new QTextEdit(this);
te2->setText(tr("可关闭"));
dock->setWidget(te2);
addDockWidget(Qt::RightDockWidgetArea,dock);
}
MainWindow::~MainWindow()
{
delete ui;
}
6.分割窗口
QSplitter
#include "mainwindow.h"
#include <QApplication>
#include <QSplitter>
#include <QTextEdit>
#include <QFont>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QFont font("ZYSong18030",12);
a.setFont(font);
QSplitter *splitterMain = new QSplitter(Qt::Horizontal,0);
QTextEdit *textLeft = new QTextEdit(QObject::tr("Left Widget"),splitterMain);
textLeft->setAlignment(Qt::AlignCenter);
QSplitter *splitterRight = new QSplitter(Qt::Vertical,splitterMain);
splitterRight->setOpaqueResize(false);
QTextEdit *textUp = new QTextEdit(QObject::tr("Top Widget"),splitterRight);
textUp->setAlignment(Qt::AlignCenter);
QTextEdit *textBottom = new QTextEdit(QObject::tr("Bottom Widget"),splitterRight);
textBottom->setAlignment(Qt::AlignCenter);
splitterMain->setStretchFactor(1,1);
splitterMain->setWindowTitle(QObject::tr("Splitter"));
splitterMain->show();
return a.exec();
}