如何让 Qt 识别 QMYSQL 驱动程序

2024-03-25

我试图从 Qt 应用程序访问 MySql 数据库,但出现以下错误:

QSqlDatabase: QMYSQL driver not loaded
QSqlDatabase: available drivers: QSQLITE QSQLITE2

我觉得这很奇怪,因为我的 Qt 文件夹中有 libqsqlmysql.so 。我什至尝试将 MySql 驱动程序编译为静态插件并将其添加到我的 .pro 文件中,如下所示:

QTPLUGIN += qsqlmysql

但这也会生成相同的运行时错误(它必须找到插件,因为编译应用程序没有错误)

我缺少什么?我想避免从源代码编译 Qt,因为这也必须在部署计算机上无缝工作。

顺便说一句:即使我在 Linux 上进行开发和测试,我也需要支持 Windows。我在 Windows 上会遇到同样的问题吗?如何在 Linux 和 Windows 中编译并链接 MySql 驱动程序?

解决方案:

在遵循@Sergey的建议之后,我对应用程序进行了跟踪,将输出重定向到grep,这样我就可以搜索“mysql”,令我惊讶的是应用程序wasn't在 QTDIR/plugins/sqldrivers 寻找插件,我有 libqsqlmysql.so,它was查看 QTDIR/lib。将插件复制到 lib 文件夹后,MySql 连接就可以工作了。


尝试使用 dlopen() 打开共享库,看看它是否加载,如果没有加载,dlerror() 会告诉您什么。我在 Windows 上总是遇到类似的问题。 LoadLibrary()/GetLastError() 救了我很多次(上次是因为某些 libiconv/libintl DLL 的版本错误)。在插件上运行 ldd 也可能有帮助。

如果 dlopen() 工作正常,请尝试使用 QPluginLoader 加载插件。如果未加载,请检查插件的 buildkey。我通常通过在插件上运行字符串然后查找“buildkey”或“QT_PLUGIN_VERIFICATION_DATA”等字符串来完成此操作。只需查看构建密钥及其周围的内容可能会给您一个想法。例如,您可能会意识到您已经在发布模式下编译了插件,而您的应用程序是在调试模式下编译的。在这种情况下,构建密钥将不匹配,并且插件将无法加载。构建密钥中的所有内容都必须与您的配置匹配。请注意,版本和构建密钥的检查方式不同:构建密钥必须完全匹配(或匹配一些称为 QT_BUILD_KEY_COMPAT 的黑魔法),但在版本中只有主要版本必须完全匹配,次要版本必须是 Qt 的版本插件是用 或更高版本编译的,并且补丁级别被忽略。因此,如果您的插件是使用 Qt 4.x.y 编译的,那么它将适用于 Qt 版本 4.z.*(其中 z>=x)。这实际上是有道理的。

如果构建密钥看起来没问题(如果您达到了这一点,则不太可能),您可能希望查看 QLibraryPrivate::isPlugin() 源代码以找出问题所在,但这对我来说似乎不是一件容易的事(尽管在调试器中运行它可能会有所帮助)。

如果 QPluginLoader 确实加载了插件,请检查它是否位于正确的目录中并且具有正确的权限。如果此时您仍然没有解决问题,那么是时候查看实际加载这些插件的 SQL 模块源代码了。但这是极不可能的。我多次遇到这个问题,总是要么库未加载,要么构建密钥不匹配。

QPluginLoader 成功加载插件后的另一种方法是使用 strace 来确定程序是否至少尝试打开插件文件。在 strace 输出中搜索诸如“sqldrivers”或“plugins”之类的内容也应该给出 Qt 搜索其插件(特别是 SQL 驱动程序)的目录。

Update

是否可以将驱动程序编译为静态插件而不用担心任何事情?咱们试试吧:

d:\Qt4\src\plugins\sqldrivers\psql>qmake CONFIG+=static LIBS+=-Ld:/programs/Post
greSQL/lib INCLUDEPATH+=d:/programs/PostgreSQL/include
d:\Qt4\src\plugins\sqldrivers\psql>make

它编译得很好,现在我在 QTDIR/plugins/sqldrivers 中得到了 libqsqlpsql.a (发布)和 libqsqlpsqld.a (调试)(它isWindows 上正确的位置)。我在这里使用 PostgreSQL 驱动程序,但我认为这对于我没有安装的 MySQL 来说不会有任何不同。好吧,让我们用它编译一些真正的程序:

d:\alqualos\pr\archserv>qmake QTPLUGIN+=qsqlpsql PREFIX=d:/alqualos LIBS+=-Ld:/g
nu/lib INCLUDEPATH+=d:/gnu/include LIBS+=-Ld:/programs/PostgreSQL/lib LIBS+=-lpq

请注意,我必须手动链接到 libpq,否则链接器会抱怨未定义的引用。有趣的是,qmake 知道 qsqlpsql 位于 QTDIR/plugins/sqldrivers 中,并相应地设置编译器和链接器选项。所以它仍然需要在正确的地方工作,只是你不必担心你的用户遇到同样的问题,因为它只在编译期间使用。另一种选择是只使用LIBS+=-Lpath/to/plugin LIBS+=-lqsqlpsql代替QTPLUGIN+=qsqlpsql,至少文档说它应该有效,但我还没有测试过。

为了让应用程序实际使用该插件,我必须将以下内容放入我的主单元(CPP 文件)中:

#include <QtPlugin>
Q_IMPORT_PLUGIN(qsqlpsql)

有用!另外,从我从来源中了解到的情况来看,只有在动态加载插件时才会检查构建密钥和版本(所有相关内容都在 QLibrary 的私有类中,甚至不在 QPluginLoader 中)。因此,生成的可执行文件可能(也可能不会,取决于二进制兼容性)即使在不同版本和构建的 Qt 上也能工作,尽管与旧版本一起使用可能会触发一些稍后修复的错误。

还值得注意的是,加载 SQL 驱动程序的顺序是这样的:使用静态链接到 Qt 的驱动程序(如果可用),然后查找使用 QSqlDatabase::registerSqlDriver() 手动注册的驱动程序,然后查找静态导入到应用程序中的驱动程序(上面介绍的方式),最后尝试加载一个共享插件。因此,当您静态链接时,您的用户将无法使用他们可能已经拥有的动态链接驱动程序,但可以使用静态链接到 Qt 中的驱动程序(如在 Ubuntu 中)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何让 Qt 识别 QMYSQL 驱动程序 的相关文章

  • 如何获取对话框/窗口的背景颜色?

    如何获取 RGB 格式的对话框 窗口的背景颜色 Use QWidget palette访问小部件的调色板和QPalette color获取背景颜色 color widget palette color QPalette Background
  • Q_PROPERTY NOTIFY 信号及其参数

    我有写 propertyChanged 的习惯signals 带参数 这样接收端就不需要调用Q PROPERTY s READ明确地发挥作用 我这样做是出于清晰的考虑 并且假设在 QML 数据绑定情况下 不需要对 getter 进行 昂贵
  • Qml中的QScrollArea:Flickable + QQuickPaintedItem

    我正在尝试实现类似的东西QScrollArea 在小部件世界中 在 Qml 的帮助下 我决定一探究竟Flickable plus QQuickPaintedItem基于项目 在我的例子中名为抽屉 Flickable onContentXCh
  • Qt - 如何将数据与 QTableWidgetItem 关联?

    我想将附加数据与插入表中的每个 QTableWidgetItem 相关联 以便将来在单击表项时使用该数据 但这些数据不应该是可见的 我怎样才能做到这一点 您可以使用QTableWidgetItem setData http doc qt i
  • Qt 样式表:无法使用 ID 选择器

    我正在学习使用 Qt 样式表向我的应用程序添加不同的样式 我在网上查看了 Qt 文档 其中说你可以使用名为ID Selector可以将主题应用于某些对象 这就是我实现此功能的方式 QPushButton button color red 但
  • Qt 信号和槽、线程、app.exec() 以及相关查询

    相关这个问题 https stackoverflow com questions 1450500 我写这段代码是为了理解 qt 信号和槽是如何工作的 我需要有人来解释这种行为 并告诉我我自己的结论是否正确 我的程序 connectionha
  • 如何在 Qt 中实现 QHoverEvent?

    我正在学习 Qt 和 C 我已经成功地实现了信号和槽来捕获标准事件 例如ButtonPushed 等等 但是 我希望当我将鼠标悬停在鼠标上并移出鼠标时调用一个函数QLabel 看起来像QHover事件 http doc qt io qt 4
  • Ncurses 和 Qt 互操作性

    拥有基于 Qt 和 ncurses 的应用程序 在等待用户输入时每秒刷新屏幕的最佳方法是什么 例如显示时钟并获取用户输入 我需要 CPU 使用率和应用程序响应能力之间的最佳折衷 更具体地说 如何获取用户输入并仍然使用QTimer以及信号槽机
  • 在Linux上运行MFC程序

    我有一个相当大的基于 MFC 的程序 我的任务是让它在 Linux 上运行 我已经解释过 这需要将程序重新编写为带有 STL 的直接 C 更多工作 或者重新编写为 Qt C 更少工作 现在我被告知 我需要编写包装器以使每个 MFC 类在 L
  • QtWebKit 无需安装 flash 播放器即可播放 HTML5 视频

    安装最新的 Flash 播放器并启用插件后 我的简单示例可以播放 YouTube 视频 操作系统 Windows 7 Qt 4 7 4 32 位和 64 位均可 但是 根据 http www youtube com html5 我的示例浏览
  • 为什么我的自定义图形项目在基于 Qt 的 C++ GUI 应用程序中不断重新绘制?

    我的应用程序有一个 QMdiArea 其中显示子窗口 其中包含 QGraphicsView 派生视图 GfxInteractiveView 的实例 这些视图又可视化包含自定义 QGraphicsItem 派生项目的场景 An image i
  • 如何使用 qt 在键盘上仅显示数字

    我在我的项目中使用 Qt Quick Virtual Keyboard 当我单击一个对象时 我想显示键盘但只显示数字 我怎样才能做到这一点 这就是我想做的 您可以使用Qt ImhFormattedNumbersOnly http doc q
  • Qt、QML 和 Windows 8 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我一直对Qt框架引入的QML很好奇 但从未有机会使用它 但现在随着 Windows 8 的到来 基于旧式小部件的界面将变得过时 只是我
  • 如何在子进程期间和之后执行操作

    我有一个调用子程序的程序 当子程序使用 Popen 运行时 我需要禁用运行按钮并启用停止按钮 但是 由于Popen打开了一个新进程 因此程序完成后应该打印的内容会立即打印出来 我尝试添加self p communicate after Po
  • 部署 Qt Quick 演示应用程序 Minehunt 时出现全白屏幕

    为了测试部署过程 我尝试部署附带的演示应用程序 Minehunt 我能够让它运行 没有崩溃或错误 但屏幕是全白的 我相信这通常意味着我缺少插件 Dependency walker 报告没有问题 我什至尝试包含 Qt MingW 插件目录中的
  • 如何安全地销毁 QThread?

    我想正确地销毁一个QThread在 Qt 5 3 中 到目前为止我已经得到 MyClass MyClass QObject parent QObject parent mThread new QThread this QObject con
  • 错误“标记不是预处理器子表达式中的有效二元运算符”

    如果我构建并运行一个项目 基本上是由 Mac OS 10 6 上的 Qt 框架生成的存根 我会得到以下错误输出 Users home Qt5 0 1 5 0 1 clang 64 include QtCore qisenum h 53 Er
  • QGeoCoordinate:没有这样的文件或目录

    我正在尝试使用 QtLocation 但不能 我不明白为什么 我在 ubuntu 14 04 上使用 qt5 3 2 这很奇怪 因为我将这一行添加到我的 pro 文件中 QT network CONFIG mobility MOBILITY
  • Qt 捕获按下的键

    我想到写原始蛇 我有一个窗口 程序可以在其中绘制随机线条 但我想不出如何捕捉按下的键来改变画线的方向 class QUpdatingPathIte public QGraphicsPathItem void advance int phas
  • 由于 QCoreApplication 事件循环,QThread 永远不会退出

    Problem 所以我有一个 CommandRetriever 类来保存一些命令 并且should在不同的线程上执行这些命令 class CommandRetriever public CommandRetriever CommandRet

随机推荐