gpt4 book ai didi

c++ - 如何在qt中所有继承类的基类中使用信号?

转载 作者:行者123 更新时间:2023-11-28 04:38:25 25 4
gpt4 key购买 nike

我有一个 qt quick 2 应用程序,我有我的 C++ 类的基类

class ManagerEngine : public QObject
{
Q_OBJECT
public:
explicit ManagerEngine(QObject *parent = nullptr);
bool isProcessing();
void setIsProcssing(bool isProcessing);
signals:
void isProcessingChanged(bool isProcessing);
private:
bool m_IsProccessing;
};

我有很多继承自上面类的类

class BookManager : public ManagerEngine
{
};

void BookManager::getList(bool refreshList){
setIsProcssing(true);
//get data from server
setIsProcssing(false);
}

现在在这些类中,我想在方法从服务器获取一些数据时显示 BusyIndi​​cator

BookPage.qml

BookManager{
id: bm
onIsProcessingChanged: {
busyIndicator.visible=isProcessing; // busyIndicator is in main.qml
}
}

CategoryPage.qml

CategoryManager{
id: cm
onIsProcessingChanged: {
busyIndicator.visible=isProcessing;
}
}

QuestionPage.qml

QuestionManager{
id: qm
onIsProcessingChanged: {
busyIndicator.visible=isProcessing;
}
}

//I have many class like : login signup and ... inherited from base class

ma​​in.qml

BusyIndicator{
id:busyIndicator
}

BookPage.qml 和...(上图)中一切正常,在这些页面中 busyIndi​​cator 将显示。但我想按时完成。

我试过这个:我使用基类 ManagerEngine 来显示 BusyIndi​​cator

我想像下面这样显示 busyIndi​​cator。(我在主页中声明了基类。现在如果我打开 BookPage.qml 来显示图书列表,现在 busyIndi​​cator 必须可见

ma​​in.qml

ManagerEngine{
id: me
onIsProcessingChanged: {
progressIndicator.visible=isProcessing;
}
}
BusyIndicator{
id:busyIndicator
}

但它不起作用。是否有另一种方法来完成这项工作(例如,我可以使用 static 关键字)

最佳答案

这永远行不通,因为这些类似乎在主线程中工作,并且当处理完成时,没有发生用户界面更新,并且您的应用程序被卡住。

在所有情况下,解决方案都必须从使忙碌指示器成为一个适当的属性开始——这将神奇地解决您的 Qt Quick 问题,并且您可以简单地绑定(bind)到该属性,而不必显式地使用信号。这就是属性通知的用途,QML 会为您处理它们。您也不希望 setter 公开 - 这是内部的只读状态。您还需要 const-correct 签名。

解决所有问题后,我们得到:

class ManagerEngine : public QObject {
Q_OBJECT
Q_PROPERTY(bool isProcessing READ isProcessing NOTIFY isProcessingChanged)
public:
using QObject::QObject; //for C++14 & up
bool isProcessing() const;
Q_SIGNAL void isProcessingChanged(bool);
protected:
void setIsProcessing(bool);
private:
bool m_isProccessing = false;
};

/// This method is not thread-safe
void ManagerEngine::setIsProcessing(bool p) {
if (p == m_isProcessing) return;
m_isProcessing = p; // precondition of the signal
return emit isProcessingChanged(m_isProcessing);
}

/// This method is not thread-safe
bool ManagerEngine::isProcessing() const {
return m_isProcessing;
}

如果您希望处理成为在管理器引擎的所有实例之间共享的状态,则使其成为类的属性,而不是对象的属性。在 C++ 中,static 成员声明意味着它是类成员,而不是对象成员。

界面

class ManagerEngine : public QObject {
Q_OBJECT
Q_PROPERTY(bool isProcessing READ isProcessing NOTIFY isProcessingChanged)
public:
using QObject::QObject; //for C++14 & up
~ManagerEngine() override;
bool isProcessing() const;
Q_SIGNAL void isProcessingChanged(bool);
protected:
void setIsProcessing(bool);
private:
bool m_isProcessing = false; // per-object
static QAtomicInt m_processingCount; // per-class
};

实现

QAtomicInt ManagerEngine::m_processingCount;

ManagerEngine::~MangerEngine() {
setIsProcessing(false);
// Perhaps it'd be more appropriate instead to simply
// Q_ASSERT(!m_isProcessing) if the engine should not be destroyed
// during processing.
}

// This method is not thread-safe, but multiple engines can
// reside in different threads.
void ManagerEngine::setIsProcessing(bool p) {
if (p == m_isProcessing) return;
int const delta = p ? (+1) : (-1);
auto count = m_processingCount.load();
Q_ASSERT(count >= 0);
Q_ASSERT(p || count > 0);
m_isProcessing = p;
while (!m_processingCount.testAndSetOrdered(count, count+delta)) {
count = m_processingCount.load();
}
// The signal will be emitted only when the global state changes,
// and exactly once per global state change.
if ((count > 0) != ((count+delta) > 0))
emit isProcessingChanged(count > 0);
return;
}

// Note: Due to data races, it is not guaranteed that the result of
// this method is the same as the parameter in the isProcessingChanged
// signal. Only the signal's parameter is guaranteed to change state
// in a race-free fashion, i.e. always toggle (alternate) and never repeat.
bool ManagerEngine::isProcessing() const {
auto const count = m_processingCount.load();
Q_ASSERT(count >= 0);
Q_ASSERT(!m_isProcessing || count > 0);
return count > 0;
}

关于c++ - 如何在qt中所有继承类的基类中使用信号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50796101/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com