Qt学习

.VS2013使用Qt

1.下载安装Qt

    去Qt官网下载qt-opensource-windows-x86-msvc2013-5.8.0.exe,安装到目录(此处安装在D盘)

2.打开VS2013新建控制台应用程序

   新建main.cpp

3.配置属性

    属性->C/C++->常规->附加包含目录:D:\Qt\Qt5.8.0\5.8\msvc2013\include

          ->连接器 ->常规->附加库目录:D:\Qt\Qt5.8.0\5.8\msvc2013\lib

          ->连接器 ->输入->附加依赖项: Qt5Core.lib;Qt5Widgets.lib;

#include "QtWidgets/QApplication"
#include "QtWidgets/QDialog"
#include "QtWidgets/QPushButton"
#include "QtWidgets/QSlider"
#include "QtWidgets/QSpinBox"
#include "QtWidgets/QBoxLayout"
#include "QtWidgets/QGridLayout"

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

    QDialog dlg;
    dlg.setWindowTitle("QDialog");

    QPushButton btn("Ok", &dlg);

    QSlider slider(Qt::Horizontal, &dlg);
    slider.setRange(0, 120);
    slider.setPageStep(10);
    slider.setValue(30);

    QSpinBox spin(&dlg);
    spin.setRange(0, 120);
    spin.setValue(30);

    QHBoxLayout layoutH;
    layoutH.addWidget(&slider);
    layoutH.addWidget(&spin);
    layoutH.addWidget(&btn);

    dlg.setLayout(&layoutH);

    // 滑动滑条改变spin的值
    QWidget::connect(&slider, SIGNAL(valueChanged(int)),
        &spin, SLOT(setValue(int)));

    // 改变spin的值移动滑条
    QWidget::connect(&spin, SIGNAL(valueChanged(int)),
        &slider, SLOT(setValue(int)));

    // 点击"Ok"关闭Dialog
    QWidget::connect(&btn, SIGNAL(clicked()),
        &dlg, SLOT(close()));

    dlg.show();

    return app.exec();
}

4.编译运行

    运行时需要到D:\Qt\Qt5.8.0\5.8\msvc2013\bin下,把libEGL.dll与libGLESv2.dll放到拷贝到可执行文件目录。

5.继承Qt类

    如实现加法计算器的Dialog

CalculatorDialog.h

#ifndef _CALCULATOR_DIALOG_H
#define _CALCULATOR_DIALOG_H

#include "QtWidgets/QDialog"

QT_BEGIN_NAMESPACE
class QLineEdit;
class QPushButton;

class CalculatorDialog : public QDialog
{
    // MOC编译器把不符合标准的语法编程标准的C++语法
    Q_OBJECT
public:
    CalculatorDialog(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());

    ~CalculatorDialog();

private slots:
    void enableCalcButton(void);

    void calcClicked(void);

private:
    QLineEdit* m_editX;
    QLineEdit* m_editY;
    QLineEdit* m_editZ;
    QPushButton* m_btnCalc;
};
QT_END_NAMESPACE

#endif

CalculatorDialog.cpp

#include "CalculatorDialog.h"
#include "QtCore/QTextCodec"
#include "QtWidgets/QLineEdit"
#include "QtWidgets/QLabel"
#include "QtWidgets/QPushButton"
#include "QtWidgets/QBoxLayout"


CalculatorDialog::CalculatorDialog(QWidget *parent /* = Q_NULLPTR */, Qt::WindowFlags f /* = Qt::WindowFlags() */)
    : QDialog(parent, f)
{
    QTextCodec* codec = QTextCodec::codecForName("GBK");

    setWindowTitle(codec->toUnicode("加法计算器"));

    m_editX = new QLineEdit(this);
    m_editY = new QLineEdit(this);
    m_editZ = new QLineEdit(this);
    m_btnCalc = new QPushButton("=", this);

    QHBoxLayout* layout = new QHBoxLayout();

    layout->addWidget(m_editX);
    layout->addWidget(new QLabel("+", this));
    layout->addWidget(m_editY);
    layout->addWidget(m_btnCalc);
    layout->addWidget(m_editZ);

    setLayout(layout);

    connect(m_editX, SIGNAL(textChanged(const QString&)),
        this, SLOT(enableCalcButton()));
    connect(m_editY, SIGNAL(textChanged(const QString&)),
        this, SLOT(enableCalcButton()));
    connect(m_btnCalc, SIGNAL(clicked()),
        this, SLOT(calcClicked()));
}


CalculatorDialog::~CalculatorDialog()
{
}

void CalculatorDialog::enableCalcButton(void)
{
    bool bXOk, bYOk;

    m_editX->text().toDouble(&bXOk);
    m_editY->text().toDouble(&bYOk);

    m_btnCalc->setEnabled((bXOk && bYOk));
}

void CalculatorDialog::calcClicked(void)
{
    double res = m_editX->text().toDouble() +
        m_editY->text().toDouble();

    QString str = QString::number(res, 'g', 15);
    m_editZ->setText(str);
}

main.cpp

#include "QtWidgets/QApplication"
#include "CalculatorDialog.h"

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

    CalculatorDialog dlg;
    dlg.show();

    return app.exec();
}

这样的三个文件编译时会出现如下问题:

1>CalculatorDialog.obj : error LNK2001: 无法解析的外部符号 "public: virtual struct QMetaObject const * __thiscall CalculatorDialog::metaObject(void)const " (?metaObject@CalculatorDialog@@UBEPBUQMetaObject@@XZ)
1>CalculatorDialog.obj : error LNK2001: 无法解析的外部符号 "public: virtual void * __thiscall CalculatorDialog::qt_metacast(char const *)" (?qt_metacast@CalculatorDialog@@UAEPAXPBD@Z)
1>CalculatorDialog.obj : error LNK2001: 无法解析的外部符号 "public: virtual int __thiscall CalculatorDialog::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@CalculatorDialog@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
1>..\..\bin\Calculator.exe : fatal error LNK1120: 3 个无法解析的外部命令
========== 生成:  成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========

解决方法:

    打开Qt 5.8 32-bit for Desktop(MSVC 2013)命令窗口

cd /d E:\workspace\qt\Calculator

moc CalculatorDialog.h -o moc_CalculatorDialog.cpp

此时会生成moc_CalculatorDialgo.cpp文件,然后把该文件添加到工程,即可编译通过。

注:若CalculatorDialg.h文件发生了修改,则需要重新编译生成moc_CalculatorDialog.cpp文件。

6.使用QtDesigner绘制界面并实现加法计算器

    在QtDesigner绘制出如下样式的界面后,保存到Calculator工程下,得到CalculatorDialgo.ui文件

    在Qt 5.8 32-bit for Desktop(MSVC 2013)命令窗口中执行下面的命令

uic CalculatorDialog.ui -o ui_CalculatorDialog.h

    得到ui_CalculatorDialg.h的文件,内容如下:

/********************************************************************************
** Form generated from reading UI file 'CalculatorDialog.ui'
**
** Created by: Qt User Interface Compiler version 5.8.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_CALCULATORDIALOG_H
#define UI_CALCULATORDIALOG_H

#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QDialog>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>

QT_BEGIN_NAMESPACE

class Ui_Dialog
{
public:
    QHBoxLayout *horizontalLayout;
    QLineEdit *m_editX;
    QLabel *label;
    QLineEdit *m_editY;
    QPushButton *m_btnCalc;
    QLineEdit *m_editZ;

    void setupUi(QDialog *Dialog)
    {
        if (Dialog->objectName().isEmpty())
            Dialog->setObjectName(QStringLiteral("Dialog"));
        Dialog->resize(463, 50);
        horizontalLayout = new QHBoxLayout(Dialog);
        horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
        m_editX = new QLineEdit(Dialog);
        m_editX->setObjectName(QStringLiteral("m_editX"));
        m_editX->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);

        horizontalLayout->addWidget(m_editX);

        label = new QLabel(Dialog);
        label->setObjectName(QStringLiteral("label"));
        label->setLineWidth(10);
        label->setTextFormat(Qt::AutoText);
        label->setWordWrap(true);

        horizontalLayout->addWidget(label);

        m_editY = new QLineEdit(Dialog);
        m_editY->setObjectName(QStringLiteral("m_editY"));
        m_editY->setAlignment(Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing);

        horizontalLayout->addWidget(m_editY);

        m_btnCalc = new QPushButton(Dialog);
        m_btnCalc->setObjectName(QStringLiteral("m_btnCalc"));
        m_btnCalc->setEnabled(false);

        horizontalLayout->addWidget(m_btnCalc);

        m_editZ = new QLineEdit(Dialog);
        m_editZ->setObjectName(QStringLiteral("m_editZ"));
        m_editZ->setReadOnly(true);

        horizontalLayout->addWidget(m_editZ);


        retranslateUi(Dialog);

        QMetaObject::connectSlotsByName(Dialog);
    } // setupUi

    void retranslateUi(QDialog *Dialog)
    {
        Dialog->setWindowTitle(QApplication::translate("Dialog", "Calculator", Q_NULLPTR));
        label->setText(QApplication::translate("Dialog", "+", Q_NULLPTR));
        m_btnCalc->setText(QApplication::translate("Dialog", "=", Q_NULLPTR));
    } // retranslateUi

};

namespace Ui {
    class Dialog: public Ui_Dialog {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_CALCULATORDIALOG_H

    新建一个DesignCalculatorDlg类,源码如下:

    DesignCalculatorDlg.h

#pragma once

#include "ui_CalculatorDialog.h"

class DesignerCalculatorDlg : public QDialog, Ui_Dialog
{
    Q_OBJECT
public:
    DesignerCalculatorDlg(QWidget* parent = NULL);
    ~DesignerCalculatorDlg();

private slots:
    void enableCalcButton(void);
    void calcClicked(void);

};

    DesignCalulatorDlg.cpp

#include "DesignerCalculatorDlg.h"


DesignerCalculatorDlg::DesignerCalculatorDlg(QWidget* parent)
    :QDialog(parent)
{
    setupUi(this);

    m_editX->setValidator(new QDoubleValidator(this));
    m_editY->setValidator(new QDoubleValidator(this));

    connect(m_editX, SIGNAL(textChanged(const QString&)),
        this, SLOT(enableCalcButton()));
    connect(m_editY, SIGNAL(textChanged(const QString&)),
        this, SLOT(enableCalcButton()));
    connect(m_btnCalc, SIGNAL(clicked()),
        this, SLOT(calcClicked()));
}


DesignerCalculatorDlg::~DesignerCalculatorDlg()
{
}

void DesignerCalculatorDlg::enableCalcButton(void)
{
    bool bXOk, bYOk;

    m_editX->text().toDouble(&bXOk);
    m_editY->text().toDouble(&bYOk);

    m_btnCalc->setEnabled((bXOk && bYOk));
}

void DesignerCalculatorDlg::calcClicked(void)
{
    double res = m_editX->text().toDouble() +
        m_editY->text().toDouble();

    QString str = QString::number(res, 'g', 15);
    m_editZ->setText(str);
}

    随后利用moc生成moc_DesignCalculatorDlg.cpp文件,并加入到工程。

    属性->连接器 ->输入->附加依赖项,追加Qt5Gui.lib

    这样DesignCalculatorDlg与前面的CalulatorDialog就有相同的功能了。

main.cpp

#include "QtWidgets/QApplication"
#include "CalculatorDialog.h"
#include "DesignerCalculatorDlg.h"

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

    CalculatorDialog dlg;
    dlg.show();

    DesignerCalculatorDlg designedDlg;
    designedDlg.show();

    return app.exec();
}

.字符编码

QTextCodec

eg:显示中文不乱码

QTextCodec* codec = QTextCodec::codecForName("GBK");
QLabel label(codec->toUnicode("中文"));
label.show();

.容器

1.QWidgets

    绝大多数图形相关的组件都是它的子类

2.QMainWindow

3.QDialog

.布局

1.QLayout

2.QBoxLayout/QHBoxLayout/QVBoxLayout

3.QGrigLayout

.信号与槽

使用说明:

1.一般情况信号和草参数纯虚类型要相同

eg:

QObject::connect(A, SIGNAL(sigFunc(int, string)), B, SLOT(slotFunc(int, string))); // ok

QObject::connect(A, SIGNAL(sigFunc(string, int)), B, SLOT(slotFunc(int, string))); // no

2.可以带有缺省参数

eg:

QObject::connect(A, SIGNAL(sigFunc(int)), B, SLOT(slotFunc(int, string=""))); // ok

3.信号函数参数可以多于槽函数参数,多余的参数将被忽略

eg:

QObject::connect(A, SIGNAL(sigFunc(int, string)), B, SLOT(slotFunc(int))); // ok

4.一个信号可以被连接到多个槽函数

eg:

QObject::connect(A, SIGNAL(sigFunc(int)), B1, SLOT(slotFunc(int))); // ok

QObject::connect(A, SIGNAL(sigFunc(int)), B2, SLOT(slotFunc(int))); // ok

注:当A发出信号时,B1/B2的槽函数都会被执行,执行顺序不确定

5.多个信号可以连接到同一个槽函数

eg:

QObject::connect(A1, SIGNAL(sigFunc(int)), B, SLOT(slotFunc(int))); // ok

QObject::connect(A2, SIGNAL(sigFunc(int)), B, SLOT(slotFunc(int))); // ok

注:无论A1还是A2发出信号,B的槽函数都会被执行

 

posted @ 2017-04-29 15:49  pry_up  阅读(266)  评论(0编辑  收藏  举报