1 安装
1.1 安装 VS 2022
下载链接 https://visualstudio.microsoft.com/zh-hans/downloads/
社区版免费,已足够个人开发使用。
根据个人需求选择安装组件即可,后续可通过 Visual Studio Installer 修改组件安装。
1.2 安装 Qt 5.14.2
官方下载链接 https://download.qt.io/archive/qt/5.14/5.14.2/qt-opensource-windows-x86-5.14.2.exe
以上链接目前为止是有效的,无法访问的话需科学上网。
Qt 版本自 5.15 开始不再提供离线安装包,需在线安装或者自己下载源码编译安装,因此 5.14.2 最后一个可以离线安装的版本。
安装过程中需登录 Qt 账号,最少需选择以下组件,其它按需选择即可。
详细安装步骤可参考博客 https://cloud.tencent.com/developer/article/2248312
在 Visual Studio 打开 扩展
→ 管理扩展
,搜索安装 Qt Visual Studio Tools 即可。
装好扩展后,在菜单栏 扩展
→ Qt VS Tools
→ Options
中关联 Qt。
可点击下方 Autodetect
按钮,将自动关联已安装的 Qt 版本,选择一个默认版本打勾即可。
2 配置
如果只是在 Qt 项目中使用 Qt 编程,并不需要额外配置。这里针对的情况,是在普通 C/C++ 项目中使用 Qt 编程。
2.1 设置属性表
个人喜欢通过属性表进行目录配置,这样可以避免在系统环境变量中添加额外 Qt 目录。这里我的 Qt 安装目录为 C:\ProgramLibs\Qt\
。
2.2 拷贝 dll
文件
从 C:\ProgramLibs\Qt\Qt5.14.2\5.14.2\msvc2017_64\bin
找到所需的 dll
文件,拷贝到项目文件夹中。
一般常用的 dll
文件有 Qt5Core
Qt5Gui
Qt5Widgets
等。具体需要哪些 dll
文件,可通过编译报错信息来确定。
将 C:\ProgramLibs\Qt\Qt5.14.2\5.14.2\msvc2017_64\plugins
中的 platforms
文件夹,直接拷贝到 项目文件夹\x64
中的 Debug
或 Release
中。
缺少这一步可能会引发以下报错。
详情可参考博客 https://blog.csdn.net/qq_42495740/article/details/118992097
3 测试
3.1 简单测试
安装完成后,可直接新建一个 Qt 项目来测试是否安装成功。这里选择新建 Qt Quick Application,一路默认下一步即可,最后直接点击编译运行。
3.2 在非 Qt 工程中使用 Qt
3.2.1 配置步骤
这里展示如何在一个 C++ 空项目中配置 Qt 中的钟表示例(Analog Clock Window Example)。
新建 C++ 空项目 testQt
,首先将所需的 dll
文件与已建好的属性表文件拷贝到项目文件夹。
在项目属性管理器中添加现有属性表,选择项目文件夹中已建好的 Qt 属性表文件。
将 platforms
文件夹拷贝到项目第一层目录的 x64
文件夹中的 Debug
或 Release
文件夹中。
在项目中分别建立以下头文件与源文件,代码见 3.2.2。
其中 RasterWindow.h
中存在 QObject
类,需要在项目文件夹中通过 moc
命令生成 moc_RasterWindow.cpp
文件,然后添加到项目的资源文件中。
1
| moc RasterWindow.h -o moc_RasterWindow.cpp
|
另外,如果项目中有 .ui
文件,也需要在项目文件夹中通过 uic
命令生成 .h
文件,然后添加到项目中。
3.2.2 源代码
main.cpp
1 2 3 4 5 6 7 8 9 10
| #include "AnalogClockWindow.h" #include <QtWidgets/QApplication>
int main(int argc, char *argv[]) { QApplication app(argc, argv); AnalogClockWindow* clock = new AnalogClockWindow(); clock->show(); return app.exec(); }
|
AnalogClockWindow.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include "RasterWindow.h" #include <QtCore/QTimerEvent> #include <QtGui/QPainter> #include <QtCore/QTime> #include <QtCore/QPoint> #include <QtGui/QColor>
class AnalogClockWindow : public RasterWindow { public: AnalogClockWindow(); protected: void timerEvent(QTimerEvent*) override; void render(QPainter* p) override; private: int m_timerId; };
|
AnalogClockWindow.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| #include "AnalogClockWindow.h"
AnalogClockWindow::AnalogClockWindow() { setTitle("Analog Clock"); resize(200, 200); m_timerId = startTimer(1000); } void AnalogClockWindow::timerEvent(QTimerEvent* event) { if (event->timerId() == m_timerId) renderLater(); } void AnalogClockWindow::render(QPainter* p) { static const QPoint hourHand[3] = { QPoint(7, 8), QPoint(-7, 8), QPoint(0, -40) }; static const QPoint minuteHand[3] = { QPoint(7, 8), QPoint(-7, 8), QPoint(0, -70) }; QColor hourColor(127, 0, 127); QColor minuteColor(0, 127, 127, 191); p->setRenderHint(QPainter::Antialiasing); p->translate(width() / 2, height() / 2); int side = qMin(width(), height()); p->scale(side / 200.0, side / 200.0); p->setPen(Qt::NoPen); p->setBrush(hourColor); QTime time = QTime::currentTime(); p->save(); p->rotate(30.0 * ((time.hour() + time.minute() / 60.0))); p->drawConvexPolygon(hourHand, 3); p->restore(); p->setPen(hourColor); for (int i = 0; i < 12; ++i) { p->drawLine(88, 0, 96, 0); p->rotate(30.0); } p->setPen(Qt::NoPen); p->setBrush(minuteColor); p->save(); p->rotate(6.0 * (time.minute() + time.second() / 60.0)); p->drawConvexPolygon(minuteHand, 3); p->restore(); p->setPen(minuteColor); for (int j = 0; j < 60; ++j) { if ((j % 5) != 0) p->drawLine(92, 0, 96, 0); p->rotate(6.0); } }
|
RasterWindow.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include <QtGui/QWindow> #include <QtCore/QEvent> #include <QtGui/QPainter> #include <QtGui/QResizeEvent> #include <QtGui/QBackingStore>
class RasterWindow : public QWindow { Q_OBJECT public: explicit RasterWindow(QWindow* parent = 0); virtual void render(QPainter* painter); public slots: void renderLater(); void renderNow(); protected: bool event(QEvent* event) override; void resizeEvent(QResizeEvent* event) override; void exposeEvent(QExposeEvent* event) override; private: QBackingStore* m_backingStore; };
|
RasterWindow.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| #include "RasterWindow.h"
RasterWindow::RasterWindow(QWindow* parent) : QWindow(parent) , m_backingStore(new QBackingStore(this)) { setGeometry(100, 100, 300, 200); } void RasterWindow::exposeEvent(QExposeEvent*) { if (isExposed()) renderNow(); } void RasterWindow::resizeEvent(QResizeEvent* resizeEvent) { m_backingStore->resize(resizeEvent->size()); } void RasterWindow::renderNow() { if (!isExposed()) return; QRect rect(0, 0, width(), height()); m_backingStore->beginPaint(rect); QPaintDevice* device = m_backingStore->paintDevice(); QPainter painter(device); painter.fillRect(0, 0, width(), height(), QGradient::NightFade); render(&painter); painter.end(); m_backingStore->endPaint(); m_backingStore->flush(rect); } void RasterWindow::render(QPainter* painter) { painter->drawText(QRectF(0, 0, width(), height()), Qt::AlignCenter, QStringLiteral("QWindow")); } void RasterWindow::renderLater() { requestUpdate(); } bool RasterWindow::event(QEvent* event) { if (event->type() == QEvent::UpdateRequest) { renderNow(); return true; } return QWindow::event(event); }
|