QT基础第三天(3)widget,dialog和mainwindow(内含文本编辑器例子源码)

首先我们先来看三大白板:

1.widget (小部件): widget主要是在上面放置布局控件

2.dialog (对话框): dialog有exec函数,如果是dialog窗口,后面的窗口是不能选取的

3.mainwindow (主窗口):可以显示菜单,工具栏,状态栏,托盘等功能

tips:

(1.widget和dialog都有show函数,如果通过这个函数显示这两种类型的窗口,则两个窗口都是可选的

(2.mainwindow和widget的主要区别就是能不能直接创建菜单栏等几种行为(注意:widget也可以只是要自己去定义实现,mainwidow是直接就有)

(3.dialog和mainwindow两者之间没有直接关系

一.widget

QWidgt 类是所有用户界面对象的基类。 窗口部件是用户界面的一个基本单元:它从窗 口系统接收鼠标、键盘和其它事件,并且在屏幕上绘制自己。每一个窗口部件都是矩形的, 并且它们按 Z 轴顺序排列。一个窗口部件可以被它的父窗口部件或者它前面的窗口部件盖住 一部分。

 二.dialog

QDialog 类是对话框窗口的基类。对话框窗口是主要用于短期任务以及和用户进行简要 通讯的顶级窗口。QDialog 可以是模态对话框也可以是非模态对话框。QDialog 支持扩展性并 且可以提供返回值。它们可以有默认按钮。

 例子1:

mydialog.h

#ifndef MYQDIALOG_H
#define MYQDIALOG_H

#include <QDialog>
#include <QPushButton>

class myQDialog : public QDialog
{
    Q_OBJECT   //申明当前类支持信号与槽机制,QT c++特有语法
public:
    myQDialog(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());

private:
    QPushButton *bt;
};

#endif // MYQDIALOG_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();
};

#endif // WIDGET_H

.cpp

#include "myqdialog.h"

myQDialog::myQDialog(QWidget *parent, Qt::WindowFlags f)
    :QDialog(parent, f)
{
    bt = new QPushButton("登录");
    bt->setParent(this);
    bt->setGeometry(150, 100, 100, 50);
    connect(bt, SIGNAL(clicked(bool)), this, SLOT(close()));
}

.cpp

#include "widget.h"
#include <QWidget>
#include <QDialog>
#include "myqdialog.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
//    QWidget *w = new QWidget;
//    w->setFixedSize(300, 200);
//    w->show();

    myQDialog *w = new myQDialog;
    w->setFixedSize(300, 200);
    w->exec(); //模态显示: 比show()高级
}

Widget::~Widget()
{

}

必须点击第一个才能显示出第二个

 例子2:

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPushButton>
#include <QTextEdit>
#include <QColorDialog>
#include <QErrorMessage>
#include <QFileDialog>
#include <QFontDialog>
#include <QInputDialog>
#include <QMessageBox>
#include <QProgressDialog>

class Widget : public QWidget
{
    Q_OBJECT
public slots:
    void get_font();
    void get_color();
    void get_filepath();
    void get_input();

    void show_msg();
    void show_errmsg();
    void show_progress();
public:
    Widget(QWidget *parent = 0);
    ~Widget();
private:
    QPushButton *bt_color;
    QPushButton *bt_errmsg;
    QPushButton *bt_file;
    QPushButton *bt_font;
    QPushButton *bt_input;
    QPushButton *bt_msg;
    QPushButton *bt_progress;

    QTextEdit *te;


};

#endif // WIDGET_H

.cpp

#include "widget.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    bt_color = new QPushButton("颜色");
    bt_errmsg = new QPushButton("错误消息");
    bt_file = new QPushButton("文件路径选择");
    bt_font = new QPushButton("字体选择");
    bt_input = new QPushButton("输入框");
    bt_msg = new QPushButton("消息");
    bt_progress = new QPushButton("进度");
    QVBoxLayout *vbox = new QVBoxLayout;
    vbox->addWidget(bt_color);
    vbox->addWidget(bt_errmsg);
    vbox->addWidget(bt_file);
    vbox->addWidget(bt_font);
    vbox->addWidget(bt_input);
    vbox->addWidget(bt_msg);
    vbox->addWidget(bt_progress);

    te = new QTextEdit;
    QHBoxLayout *hbox = new QHBoxLayout;
    hbox->addLayout(vbox);
    hbox->addWidget(te);
    setLayout(hbox);

    connect(bt_font, &QPushButton::clicked, this, &Widget::get_font);
    connect(bt_color, &QPushButton::clicked, this, &Widget::get_color);
    connect(bt_file, SIGNAL(clicked(bool)), this, SLOT(get_filepath()));
    connect(bt_input, SIGNAL(clicked(bool)), this, SLOT(get_input()));

    connect(bt_msg, SIGNAL(clicked(bool)), this, SLOT(show_msg()));
    connect(bt_errmsg, SIGNAL(clicked(bool)), this, SLOT(show_errmsg()));
    connect(bt_progress, SIGNAL(clicked(bool)), this, SLOT(show_progress()));
}

void Widget::show_msg()
{
    QMessageBox msgBox;
    msgBox.setText("The document has been modified.");
    msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
    qDebug() << msgBox.exec();
}

void Widget::show_errmsg()
{
    QErrorMessage emg; //TODO
    emg.showMessage("aaaaaaaaaaaaaaaaaaaaaa");
    emg.exec();
}

void Widget::show_progress()
{
    QProgressDialog progress("正在下载", "取消", 0, 100);
    progress.setValue(60);
    progress.exec();
}

void Widget::get_input()
{
    QString name = QInputDialog::getText(this, "xxx", "你的名字");
    te->append(name);
}

void Widget::get_filepath()
{
    //QString filepath = QFileDialog::getOpenFileName(); //弹出一个文件选择对话框,并且返回文件路径
    QStringList filepaths = QFileDialog::getOpenFileNames(this, "打开文件", "C://Users//ThinkPad T490//Desktop", "Images (*.png *.bmp *.jpg)"); //弹出一个文件选择对话框,并且返回一堆文件路径
    for(int i=0; i<filepaths.length(); i++)
        te->append(filepaths[i]);
}

void Widget::get_color()
{
    QColor color = QColorDialog::getColor();  //弹出一个颜色对话框,并且返回用户选择的颜色
    te->setTextColor(color);
}

void Widget::get_font()
{
//    QFontDialog *d = new QFontDialog;
//    d->exec();
    bool ok;
    QFont font = QFontDialog::getFont(&ok);  //弹出字体对话框,并且界面消失的时候反馈用户选择的字体

    if(ok)
    {
        //te->setFont(font);        //设置整个文本框的字体
        te->setCurrentFont(font);   //设置被选中的文字的字体
    }
}

Widget::~Widget()
{

}

效果:

三.mainwindow

QMainWindow 类提供一个有菜单条、锚接窗口(例如工具条)和一个状态条的主应用程序窗口。主窗口通常用在提供一个大的中央窗口部件(例如文本编辑或者绘制画布)以及周围菜单、工具条和一个状态条。QMainWindow 常常被继承,因为这使得封装中央部件、菜单和工具条以及窗口状态条变得更容易,当用户点击菜单项或者工 具条按钮时,槽会被调用。

例子实现简单的文件编辑器:

.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTextEdit>
#include <QLabel>

class MainWindow : public QMainWindow
{
    Q_OBJECT
public slots:
    void new_file();
    void open_file();
    void save_file();
    void saveas_file();
    void close_file();

    void set_font();
    void set_color();

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    QTextEdit *te;
    QLabel *lb;
};

#endif // MAINWINDOW_H

.cpp

#include "mainwindow.h"
#include <QMenu>
#include <QMenuBar>
#include <QDebug>
#include <QToolBar>
#include <QToolButton>
#include <QStatusBar>
#include <QFontDialog>
#include <QFileDialog>
#include <QFile>
#include <QMessageBox>
#include <QColorDialog>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    //0. 构造所有的action
    QAction *new_action = new QAction(QIcon(":/img/new.png"), "新建");
    new_action->setShortcut(QKeySequence("Ctrl+N"));
    connect(new_action, SIGNAL(triggered(bool)), this, SLOT(new_file()));

    QAction *open_action = new QAction(QIcon(":/img/open.png"), "打开");
    open_action->setShortcut(QKeySequence("Ctrl+O"));
    connect(open_action, SIGNAL(triggered(bool)), this, SLOT(open_file()));
    //open_action->setEnabled(false);

    QAction *saveas_action = new QAction(QIcon(":/img/saveas.png"), "另存为");
    saveas_action->setShortcut(QKeySequence("Ctrl+Y"));
    connect(saveas_action, SIGNAL(triggered(bool)), this, SLOT(saveas_file()));

    QAction *save_action = new QAction(QIcon(":/img/save.png"), "保存");
    save_action->setShortcut(QKeySequence("Ctrl+s"));
    connect(save_action, SIGNAL(triggered(bool)), this, SLOT(save_file()));

    QAction *close_action = new QAction(QIcon(":/img/close.png"), "保存");
    close_action->setShortcut(QKeySequence("Ctrl+X"));
    connect(close_action, SIGNAL(triggered(bool)), this, SLOT(close_file()));

    QAction *font_action = new QAction(QIcon(":/img/font.png"), "字体");
    font_action->setShortcut(QKeySequence("Ctrl+f"));
    connect(font_action, SIGNAL(triggered(bool)), this, SLOT(set_font()));

    QAction *color_action = new QAction(QIcon(":/img/color.png"), "颜色");
    color_action->setShortcut(QKeySequence("Ctrl+f"));
    connect(color_action, SIGNAL(triggered(bool)), this, SLOT(set_color()));

    //1. 获取菜单栏menuBar(),添加菜单->addMenu,添加选项
    QMenu *fileMenu = menuBar()->addMenu("&File"); //&F: 用键盘Alt+f
    fileMenu->addAction(new_action);
    fileMenu->addAction(open_action);
    fileMenu->addAction(save_action);
    fileMenu->addAction(saveas_action);
    fileMenu->addAction(close_action);

    QMenu *editMenu = menuBar()->addMenu("&Edit"); //&E: 用键盘Alt+e
    editMenu->addAction(font_action);
    editMenu->addAction(color_action);

    //2. 工具栏
    QToolBar *filetoolbar = addToolBar("file");   //添加一个工具栏,并且放入常用的action
    filetoolbar->addAction(new_action);
    filetoolbar->addAction(open_action);
    filetoolbar->addAction(save_action);
    filetoolbar->addAction(saveas_action);
    filetoolbar->addAction(close_action);


    QToolBar *edittoolbar = addToolBar("edit");   //添加一个工具栏,并且放入常用的action
    edittoolbar->addAction(font_action);
    edittoolbar->addAction(color_action);

    QToolBar *xxxtoolbar = addToolBar("编译");   //添加一个工具栏,并且放入常用的action
    QToolButton *tb = new QToolButton;
    tb->setText("编译");
    xxxtoolbar->addWidget(tb);
//    tb->setDisabled(true);
//    tb->setEnabled(false);

    //3. 设置中央部件
    te = new QTextEdit;
    te->setMinimumSize(640, 480);
    this->setCentralWidget(te);
    te->setDisabled(true);

    //4. 状态栏
    lb = new QLabel;
    QStatusBar *st = statusBar();
    st->addWidget(lb);


    connect(te, &QTextEdit::textChanged, [&]{
        if(!lb->text().contains('*'))
            lb->setText(lb->text()+'*');
    });

}

void MainWindow::set_font()
{
    qDebug() << "set font........";
    bool ok;
    QFont font = QFontDialog::getFont(&ok);
    if(ok)
        te->setCurrentFont(font);
}

void MainWindow::set_color()
{
    qDebug() << "set color........";
    QColor color = QColorDialog::getColor();
    te->setTextColor(color);
}
void MainWindow::new_file()
{
    qDebug() << "new........";
    te->setEnabled(true);
    if(lb->text().contains('*')) //有文件在编辑中
    {
        close_file();
    }
    else
    {
        //清除工作区
        te->clear();
        lb->clear();
    }

}

void MainWindow::open_file()
{
    qDebug() << "open........";
    te->setEnabled(true);
    //1. 提取文件路径
    QString path = QFileDialog::getOpenFileName();

    //2. 提取出文件内容 QFile
    QFile f(path);
    f.open(QIODevice::ReadOnly);
    QByteArray buf = f.readAll();
    f.close();

    //3. 将内容显示在文本编辑框
    te->setText(buf);

    //4. 显示文件路径在状态栏
    lb->setText(path);
}

void MainWindow::save_file()
{
    //1. 提取文件路径
    QString str = lb->text();
    if(!str.contains('*')) //如果文件未有改动
        return;
    str.chop(1);
    if(str.isEmpty()) //这是一个新建的文件
    {
        saveas_file();
        return;
    }

    //2. 提取文本编辑框的内容
    QString buf = te->toPlainText();

    //3. 将内容写入文件
    QFile f(str);
    f.open(QIODevice::WriteOnly);
    f.write(buf.toStdString().c_str());
    f.close();

    //4. 更新状态栏
    lb->setText(str);
}

void MainWindow::saveas_file()
{
    //1. 提取文件路径
    QString str = QFileDialog::getSaveFileName();
    if(str.isEmpty())
        return;

    //2. 提取文本编辑框的内容
    QString buf = te->toPlainText();

    //3. 将内容写入文件
    QFile f(str);
    f.open(QIODevice::WriteOnly);
    f.write(buf.toStdString().c_str());
    f.close();

    //3. 更新状态栏
    lb->setText(str);
}

void MainWindow::close_file()
{
    qDebug() << "close........";
    if(lb->text().contains('*')) //有文件被编辑中
    {
        //1. 弹框提示是否需要保存
        QMessageBox msgBox;
        msgBox.setText("The document has been modified.");
        msgBox.setInformativeText("Do you want to save your changes?");
        msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
        msgBox.setDefaultButton(QMessageBox::Save);
        int ret = msgBox.exec();

        //2. 如果要保存
        if(QMessageBox::Save == ret)
            save_file();
        else if(QMessageBox::Cancel == ret)
            return;
    }

    //清除工作区
    te->clear();
    lb->clear();
}


MainWindow::~MainWindow()
{

}

效果:

用的时候怎么选择?

窗口类型介绍:QMainWindow、QWidget、QDialog三个类都可以用来创建窗口,可以直接使用,也可以继承后使用。
  1.如果是主窗口,就使用QMainWindow类;
  2.如果是对话框,就使用QDialog类;
  3.如果不确定,有可能作为顶层窗口,也有可能嵌入到其他窗口,就使用QWidget类。

  • 18
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞赴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值