QT 学习之路

添加动作

//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:
    Ui::MainWindow *ui;

    void open();
    QAction *openAction;
};
#endif // MAINWINDOW_H


//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    /*
     * tr()函数,用于QT国际化的函数,将字符串中提取出来,用于国际化
     * 简要来说放置乱码情况出现
     */
    setWindowTitle(tr("Main Window"));

    openAction = new QAction(QIcon(":images/doc-open"),tr("&Open..."),this);//tr("&Open") 文本值前面有一个&,意味这这将成为一个快捷键       路径表示":images"从本项目的images开始检索
    openAction->setShortcuts(QKeySequence::Open);
    openAction->setStatusTip(tr("Open and existing file"));
    connect(openAction,&QAction::triggered,this,&MainWindow::open);//串联三个动作

    QMenu *file = menuBar()->addMenu(tr("&File"));
    file->addAction(openAction);

    QToolBar *toolBar = addToolBar(tr("&File"));
    toolBar-> addAction(openAction);

    statusBar();

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::open(){
    QMessageBox::information(this,tr("Information"),tr("Open"));
}

QT 学习之路_第1张图片

添加资源文件

上面示例中我们的toolbar没有图片显示,基本与背景融为一体。原因是因为我们没有配置资源文件,程序也就没办法找到那个图片进行引用。
这一步就像c#中在项目属性中添加图片类似,建立图片与程序之间的连接。
步骤:

  1. 文件->新建->AT->QT Resources File
    QT 学习之路_第2张图片
  • 我们在下方点击Add Prefix添加路径名称,也就是下面的前缀
    QT 学习之路_第3张图片
  • 点击Add Files 添加图片文件,目前支持.png 其他格式需要通过安装插件来实现,添加完成后,可以给图片一个别名。因为项目与图片之间存在引用关系,如果定义一个别名,在后面应用中如果修改项目名称,我们依旧可以正确的引用图片。最下面的语言则是为了适配国际化做的选项。填入语言将会新建一个相应语言的文件夹,系统识别后自动切换到相应路径
    QT 学习之路_第4张图片
  1. 之后我们将原有文件中路径修改为:/images/doc-test
    QT 学习之路_第5张图片

布局管理器

实现一个slider与spinbox的数据联动

设计的知识点主要是函数指针,在刚开始学习c++的时候会对这个知识点不是很熟悉。
函数指针指向某种特定类型,函数的类型由其参数及返回类型共同决定,与函数名无关,ex:

 int add(int left,int right);//定义函数
int(*pf)(int,int);//未初始化
pf = add;//通过赋值使得函数指针指向某具体函数

(*pf)两端的括号需要加上否则就变成一个int * 整型的函数

布局管理器类似于WPF和winForm中的Grid,StackPanel控件
代码:

#include "mainwindow.h"

#include
#include
#include 
#include 
#include 
#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QWidget window;
    window.setWindowTitle("Enter your age");

    QSpinBox *spinBox = new QSpinBox(&window);
    QSlider *slider = new QSlider(Qt::Horizontal,&window);
    spinBox->setRange(0,130);
    slider ->setRange(0,130);

    QObject::connect(slider,&QSlider::valueChanged,spinBox,&QSpinBox::setValue);
    void(QSpinBox::*spinBoxSignal)(int) = &QSpinBox::valueChanged;
    QObject::connect(spinBox,spinBoxSignal,slider,&QSlider::setValue);

    QHBoxLayout *layout = new QHBoxLayout;
    layout -> addWidget(spinBox);
    layout -> addWidget(slider);
    window.setLayout(layout);


    window.show();
    return a.exec();
}

添加对话框

主要的函数为QDialog,通过创建函数,并在函数中创建相应控件即可达到相应的效果。如果之前接触过WPF或Winform这块应该挺好理解的。

博主在这篇课题中提到了模块对话框与非模态对话框,在QT中模态对话框是通过

dialog.exec();

实现,非模态则是和C#中一样通过show()实现。但是这会出现一个问题,在C#中可以通过使用showDialog()函数,让窗口一直显示,但是在QT中需要通过将QDialog放置在堆上进行运行。

这是因为,show()函数不会阻塞当前线程,对话框会显示出来,然后函数立即返回,代码继续执行。注意,dialog 是建立在栈上的,show()函数返回,MainWindow::open()函数结束,dialog 超出作用域被析构,因此对话框消失了。知道了原因就好改了,我们将 dialog 改成堆上建立,当然就没有这个问题了:

如果需要指定父窗口,只需要在初始化的时候将父窗口传入即可,当父窗口为NULL的时候,该窗口将会作为一个顶层窗口。
模态有父窗口


void MainWindow::open(){
    //QMessageBox::information(this,tr("Information"),tr("Open"));
    QDialog dialog(this);
    dialog.setWindowTitle(tr("Hello ,dialog!"));
    dialog.exec();
}


QT 学习之路_第6张图片

非模态窗口

void MainWindow::open(){
    QDialog *dialog = new QDialog;
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    dialog->setWindowTitle("Hello Dialog!");
    dialog->show();
}

QT 学习之路_第7张图片

QMessageBox

QT的内置对话框大致分为以下几类:

  • QColorDialog:选择颜色;
  • QFileDialog:选择文件或者目录;
  • QFontDialog:选择字体;
  • QInputDialog:允许用户输入一个值,并将其值返回;
  • QMessageBox:模态对话框,用于显示信息、询问问题等;
  • QPageSetupDialog:为打印机提供纸张相关的选项;
  • QPrintDialog:打印机配置;
  • QPrintPreviewDialog:打印预览;
  • QProgressDialog:显示操作过程。

QMeaageBox消息提示,会含有下面几个重载:

  static int question(QWidget *parent, const QString &title,
                        const QString& text,
                        int button0, int button1 = 0, int button2 = 0);
    static int question(QWidget *parent, const QString &title,
                        const QString& text,
                        const QString& button0Text,
                        const QString& button1Text = QString(),
                        const QString& button2Text = QString(),
                        int defaultButtonNumber = 0,
                        int escapeButtonNumber = -1);
    inline static int question(QWidget *parent, const QString &title,
                               const QString& text,
                               StandardButton button0, StandardButton button1)
    { return question(parent, title, text, StandardButtons(button0), button1); }

我的QT是5.14.2路径是

E:\Qt\Qt5.14.2\5.14.2\mingw73_64\include\QtWidgets

这个函数如果熟悉C#的人可能会很快和我们经常使用的

Microsoft.VisualBasic.Interaction
QT 学习之路_第8张图片

这个函数联系在一起,只不过C#中的定义会比QT中要轻松许多,但是他们的效果是差不多的

下面是QT中的代码部分:

void MainWindow::open(){
    //QMessageBox::information(this,tr("Information"),tr("Open"));
    if(QMessageBox::Yes == QMessageBox::question(this,tr("Question"),tr("Are you OK?"),QMessageBox::Yes|QMessageBox::No|QMessageBox::Save,QMessageBox::Yes)){
        QMessageBox::information(this,tr("Hmmm..."),tr("I'm glab to hear that!"));
    }else{
        QMessageBox::information(this,tr("Hmmm..."),tr("I'm sorry!"));
    }
}

QT 学习之路_第9张图片
QT 学习之路_第10张图片

添加文件对话框

看了一段时间的博客之后发现如果之前有Winform或者是WPF的基础的话,对于目前学到的知识很容易掌握,这应该就是触类旁通的意思。
首先贴一下打开和保存的代码,通过定义文件的Mode这一步与C#的流文件模式类似,读写,读,写集中类别。

void MainWindow::openFile(){
    QString path = QFileDialog::getOpenFileName(this,tr("Open File"),".",tr("Text Files(*.txt)"));

    if(!path.isEmpty()){
        QFile file(path);
        if(!file.open(QIODevice::ReadOnly|QIODevice::Text)){
            QMessageBox::warning(this,tr("Read File"),tr("Cannot open file:\n%1").arg(path));
            return;
        }
        QTextStream in(&file);
        textEdit->setText(in.readAll());
        file.close();
    }else{
        QMessageBox::warning(this,tr("Path"),tr("You did not select any file"));
    }
}

void MainWindow::saveFile(){
    QString path = QFileDialog::getSaveFileName(this,tr("&Save File"),".",tr("Text Files(*.txt"));
    if(!path.isEmpty()){
        QFile file(path);
        if(!file.open(QIODevice::WriteOnly|QIODevice::Text)){
            QMessageBox::warning(this,tr("Write File"),tr("Cannot save file:\n%1").arg(path));
            return;
        }
        QTextStream out(&file);
        out<toPlainText();
        file.close();
    }else{
        QMessageBox::warning(this,tr("Path"),tr("You did not select any file"));
    }
}

之后我们需要在主窗口界面创建打开动作与保存动作,并使用连接器连接起来,之后创建一个文本编辑器QT里面叫做TextEditWinform或是WPF中叫做TextBox,这里有个参数SetCentralWidgrt可以将窗口放到父窗口的中心位置。 如果刚接触C++的人照着写可能会出错,因为没有在头文件中定义saveFile和TextEdit的指针,还需要再头文件中加入这两个参数才可以。
关于OPenFile函数,解释引用博主的材料

在openFile()函数中,我们使用QFileDialog::getOpenFileName()来获取需要打开的文件的路径。这个函数具有一个长长的签名:

                      QString getOpenFileName(QWidget * parent = 0,
                       const QString & caption = QString(),
                       const QString & dir = QString(),
                 const QString & filter = QString(),
                   QString * selectedFilter = 0,
                     Options options = 0)
                       ```
不过注意,它的所有参数都是可选的,因此在一定程度上说,这个函数也是简单的。这六个参数分别>是:

parent:父窗口。我们前面介绍过,Qt 的标准对话框提供静态函数,用于返回一个模态对话框(在一定程度上这就是外观模式的一种体现);
caption:对话框标题;
dir:对话框打开时的默认目录,“.” 代表程序运行目录,“/” 代表当前盘符的根目录(特指 Windows 平台;Linux 平台当然就是根目录),这个参数也可以是平台相关的,比如“C:\”等;
filter:过滤器。我们使用文件对话框可以浏览很多类型的文件,但是,很多时候我们仅希望打开特定类型的文件。比如,文本编辑器希望打开文本文件,图片浏览器希望打开图片文件。过滤器就是用于过滤特定的后缀名。如果我们使用“Image Files(.jpg .png)”,则只能显示后缀名是 jpg 或者 png 的文件。如果需要多个过滤器,使用“;;”分割,比如“JPEG Files(.jpg);;PNG Files(.png)”;
selectedFilter:默认选择的过滤器;
options:对话框的一些参数设定,比如只显示文件夹等等,它的取值是enum QFileDialog::Option,每个选项可以使用 | 运算组合起来。

# mainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:
    Ui::MainWindow *ui;

    void open();
    void openFile();
    void saveFile();
    QAction *openAction;
    QAction *saveAction;
    QTextEdit *textEdit;
};
#endif // MAINWINDOW_H

//MainWinodw.cpp
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    /*
     * tr()函数,用于QT国际化的函数,将字符串中提取出来,用于国际化
     * 简要来说放置乱码情况出现
     */
    setWindowTitle(tr("Main Window"));

    openAction = new QAction(QIcon(":images/doc-test"),tr("&Open..."),this);//tr("&Open") 文本值前面有一个&,意味这这将成为一个快捷键
    openAction->setShortcuts(QKeySequence::Open);
    openAction->setStatusTip(tr("Open and existing file"));
    //connect(openAction,&QAction::triggered,this,&MainWindow::open);//串联三个动作

    saveAction = new QAction(QIcon(":images/doc-test"),tr("&Save..."),this);
    saveAction->setShortcuts(QKeySequence::Save);
    saveAction->setStatusTip(tr("Save as a new file"));

    connect(openAction,&QAction::triggered,this,&MainWindow::openFile);
    connect(saveAction,&QAction::triggered,this,&MainWindow::saveFile);


    QMenu *file = menuBar()->addMenu(tr("&File"));
    file->addAction(openAction);
    file->addAction(saveAction);

    QToolBar *toolBar = addToolBar(tr("&File"));
    toolBar-> addAction(openAction);
    toolBar->addAction(saveAction);



    textEdit = new QTextEdit(this);
    setCentralWidget(textEdit);



    statusBar();

}

//main.cpp
#include "mainwindow.h"

#include
#include
#include 
#include 
#include 
#include 
#include "newspaper.h"
#include "reader.h"

int main(int argc, char *argv[])
{
//   QCoreApplication app(argc,argv);
//   Newspaper newspaper("NewsPaper A");

//   Reader reader;

//   QObject::connect(&newspaper,&Newspaper::newPaper,&reader,&Reader::receriveNewpaper);
//   newspaper.send();
    /*
     * 控制MainWinodow.cpp中控件显示
     */
    QApplication app(argc,argv);

    MainWindow mainWindow;
    mainWindow.show();
    return app.exec();
}

事件

Event,语法和c#类似,只是写的形式会出现区别。通过调用事件绑定操作。

#event.h
#ifndef EVENT_H
#define EVENT_H

#endif // EVENT_H

#include 

class EventLabel:public QLabel{
protected:
    void mouseMoveEvent(QMouseEvent *ev) ;
    void mousePressEvent(QMouseEvent *ev) ;
    void mouseReleaseEvent(QMouseEvent *ev) ;
};
#main.cpp


#include "mainwindow.h"

#include
#include
#include 
#include 
#include 
#include 
#include 
#include "newspaper.h"
#include "event.h"
#include "reader.h"
#include 


int main(int argc, char *argv[])
{
//   QCoreApplication app(argc,argv);
//   Newspaper newspaper("NewsPaper A");

//   Reader reader;

//   QObject::connect(&newspaper,&Newspaper::newPaper,&reader,&Reader::receriveNewpaper);
//   newspaper.send();
    /*
     * 控制MainWinodow.cpp中控件显示
     */

    QApplication app(argc,argv);

//    MainWindow mainWindow;
//    mainWindow.show();
    EventLabel *label = new EventLabel;
    label->setWindowTitle("MouseEvent Demo");
    label->resize(300,200);
    label->show();
    return app.exec();
}

void EventLabel::mouseMoveEvent(QMouseEvent *ev){
    this->setText(QString("

Move: (%1,%2)

") .arg(QString::number(ev->x()),QString::number(ev->y()))); } void EventLabel::mousePressEvent(QMouseEvent *ev){ this->setText(QString("

Press: (%1,%2)

") .arg(QString::number(ev->x()),QString::number(ev->y()))); } void EventLabel::mouseReleaseEvent(QMouseEvent *ev){ QString msg; msg.sprintf("

Relase: (%d,%d)

",ev->x(),ev->y()); this->setText(msg); }

你可能感兴趣的:(C++,QT)