避免使用qRegisterMetaType(指针与引用),关注const

时间:2015-08-23 13:46:16

标签: qt

鉴于信号:

void dbConnected(const QSqlDatabase &db);

我(从Qt Communication betwen threads, app design)学会了如何避免使用

qRegisterMetaType<QSqlDatabase>("QSqlDatabase");

只需将信号更改为此格式:

void dbConnected(QSqlDatabase *db);

而且,在插槽方面,我会使用类似的东西:

void onDBConnected(QSqlDatabase * const db);

我关注db的用法(因为在开始时我已经创建了引用const),所以我在这里使它成为const(在插槽方面)。我试图在信号方面用

做同样的事情

void dbConnected(QSqlDatabase * const db);

但是这样做我有运行时错误(在Qt Communication betwen threads, app design中提到)。所以我尝试了另一种形式,似乎可以完成这项工作:

void dbConnected(QSqlDatabase *db) const;

我是朝着正确的方向吗?

1 个答案:

答案 0 :(得分:2)

  

我是朝着正确的方向吗?

也许。首先,确保您知道无法将数据库传递给另一个线程中的对象。这是你在另一个问题的代码中犯的重大错误之一。不要那样做了。

如果您通过引用传递对象,则它必须是可复制的。打开后,QSqlDatabase可以复制 。所以你也可以在这里。

但您可能根本不需要传递数据库引用。 QSqlDatabase为每个连接分配一个名称。您可以改为传递连接名称,而不是通过值或指针传递数据库,并使用QSqlDatabase::database来获取表示给定连接的数据库对象。

例如:

class Opener : public QObject {
  Q_OBJECT
  QSqlDatabase m_db;
public:
  Q_SIGNAL void dbOpened(const QString &);
  void open() {
    m_db.addDatabase("FOO", "cats");
    ...
    if (m_db.open()) emit dbOpened(m_db.connectionName());
  }
};

class DbUser : public QObject {
  Q_OBJECT
  QSqlDatabase m_db;
public:
  Q_SLOT void onDbOpened(const QString & conn) {
    m_db = QSqlDatabase::database(conn);
  }
  ...
};

如您所见,dbOpened信号不是数据库,而是数据库连接名称,然后希望使用该连接的各种对象可以按名称检索数据库对象(句柄)。