zoukankan      html  css  js  c++  java
  • Qt学习

    .VS2013使用Qt

    1.下载安装Qt

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

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

       新建main.cpp

    3.配置属性

        属性->C/C++->常规->附加包含目录:D:QtQt5.8.05.8msvc2013include

              ->连接器 ->常规->附加库目录:D:QtQt5.8.05.8msvc2013lib

              ->连接器 ->输入->附加依赖项: 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:QtQt5.8.05.8msvc2013in下,把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>....inCalculator.exe : fatal error LNK1120: 3 个无法解析的外部命令
    ========== 生成:  成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========

    解决方法:

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

    cd /d E:workspaceqtCalculator
    
    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的槽函数都会被执行

     

  • 相关阅读:
    numpy 支持切片取值,使用ix_ 也可以取到
    pyinstaller 打包文件成 exe
    matplotlib 直方图概率不为1
    小提琴图 ValueError: object arrays are not supported
    pip 生成 requirements.txt
    CF1515E(连续段 dp)
    Lg7 月赛(构造,树形 dp)
    [省选联考 2020 A 卷] 组合数问题 题解报告
    愤怒的小 N 题解报告
    CF32E 题解
  • 原文地址:https://www.cnblogs.com/ziyu-trip/p/6784478.html
Copyright © 2011-2022 走看看