[vs+qt]VS联合QT编程,在构造函数中已经声明并实例化了子类对象,但是在槽函数中使用的话却显示 未定义标识符

项目场景:

在做一个主界面线程调用子线程进行进度条显示的测试项目中,出现了在构造函数中已经声明并实例化了子类对象,但是在槽函数中使用的话却显示”未定义标识符” 这种错误。


问题描述

直接给贴上项目部分代码:

ProgressBar::ProgressBar(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    this->setFixedSize(600, 400);
    
    QPushButton* btn1 = new QPushButton(QString::fromLocal8Bit("开启线程"),this);
    btn1->setGeometry(260, 180, 80, 40);

    bar1 = new QProgressBar(this);
    bar1->setGeometry(60, 280, 520, 20);
    bar1->setRange(0, 100);
    bar1->setValue(0);
   
    Bar* bar = new Bar(this);//这里是子线程的声明加实例对象过程

    connect(btn1, &QPushButton::clicked, this, &ProgressBar::slot_startXc);
    connect(bar, &Bar::sendVaule, this, &ProgressBar::slot_acceptValue);
}

void ProgressBar::slot_startXc()
{
    bar->start();//这里是问题出现的地方,显示bar是未定义的标识符
}

原因分析:

平时使用的话,像上述那种实例化出对象之后就直接使用了,所以一共有两种写法:
1.先在头文件中进行声明指针变量,然后在cpp文件中进行实例并分配地址

private:
    Ui::ProgressBarClass ui;
    Bar* bar;
    QProgressBar* bar1;
    bar = new Bar(this);
    bar1 = new QProgressBar(this);

2.在cpp中使用的时候一起进行声明加实例化

    QPushButton* btn1 = new QPushButton(QString::fromLocal8Bit("开启线程"),this);
    btn1->setGeometry(260, 180, 80, 40);

但是没有过这次的情况,一时间无从下手,经过查找,最终发现问题:
可能是由于Bar* bar被声明在构造函数的局部作用域内,因此在槽函数slot_startX函数中无法访问。

解决方案:

将 Bar* bar 声明为ProgressBar类的私有成员变量,这样它就可以在整个类中使用,包括在slot_startXc函数中。即第一种实例化对象的方法

下面是类的头文件

class ProgressBar : public QWidget
{
    Q_OBJECT

public:
    ProgressBar(QWidget *parent = nullptr);
    ~ProgressBar();

private:
    Ui::ProgressBarClass ui;
    Bar* bar;//!!!!!!!!★★★★★★
    QProgressBar* bar1;

private slots:
    void slot_startXc();
    void slot_acceptValue(int value);
};

本文为自己学习记录,bug问题多样,欢迎交流讨论,仅供参考!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 在Qt创建单线程的实例类,可以通过继承QObject类并重写run()函数来实现。 首先,我们创建一个继承自QObject的类,命名为MyThread。在MyThread类的头文件声明一个私有的QThread成员变量,以及一个run()函数的重载。 ```cpp #ifndef MYTHREAD_H #define MYTHREAD_H #include <QObject> #include <QThread> class MyThread : public QObject { Q_OBJECT public: explicit MyThread(QObject *parent = nullptr); void start(); void stop(); signals: void finished(); private: QThread m_thread; private slots: void run(); }; #endif // MYTHREAD_H ``` 在MyThread类的实现文件,我们可以在构造函数将m_thread设置为线程,并将自身对象移到该线程执行。 ```cpp #include "mythread.h" MyThread::MyThread(QObject *parent) : QObject(parent) { moveToThread(&m_thread); } void MyThread::start() { m_thread.start(); } void MyThread::stop() { m_thread.quit(); m_thread.wait(); } void MyThread::run() { // 在这里进行单线程的运算或操作 emit finished(); } ``` 通过这种方式创建的MyThread类,可以被当作一个普通的QObject对象使用。可以调用start()函数来开始运行单线程的操作,调用stop()函数来停止线程的执行。 在Qt主线程,可以通过连接MyThread对象的finished信号来获知操作已经完成。 ### 回答2: 在Qt,可以通过继承QObject类并在该类创建一个单独的线程实例来实现单线程的功能。 首先,在实例类添加一个成员变量用于存储线程实例: ```cpp QThread* m_thread; ``` 然后,在实例类的构造函数创建该线程实例,并将对象移动到该线程: ```cpp m_thread = new QThread(this); this->moveToThread(m_thread); ``` 接下来,在实例类的析构函数释放线程资源: ```cpp m_thread->quit(); m_thread->wait(); delete m_thread; ``` 最后,在实例类添加一个函数,用于处理单线程执行的具体逻辑: ```cpp void MyObject::run() { // 执行单线程逻辑 } ``` 在实际使用时,可以通过信号机制将其他对象的信号与此函数连接起来,触发单线程的执行: ```cpp MyObject myObject; QTimer::singleShot(0, &myObject, SLOT(run())); ``` 以上就是在Qt实例类创建一个单线程的方法。通过使用QThread类和信号机制,可以实现简单而有效的单线程执行。 ### 回答3: 在QT创建一个单线程可以通过以下步骤实现: 1. 首先,我们需要在主函数初始化QT应用程序对象,代码如下: ``` #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); // 其他代码 return a.exec(); } ``` 2. 创建一个继承自QObject的类,作为单线程的实例类,代码如下: ``` #include <QObject> class MyThread : public QObject { Q_OBJECT public: MyThread(QObject *parent = nullptr); void run(); signals: // 自定义信号 public slots: // 自定义函数 }; MyThread::MyThread(QObject *parent) : QObject(parent) { // 构造函数 } void MyThread::run() { // 线程的实际工作 } ``` 3. 在主函数创建单线程的实例并启动线程,代码如下: ``` #include "mythread.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); MyThread thread; // 连接信号和 QThread workerThread; thread.moveToThread(&workerThread); QObject::connect(&workerThread, SIGNAL(started()), &thread, SLOT(run())); workerThread.start(); // 其他代码 return a.exec(); } ``` 通过以上步骤,我们可以在QT实例类成功创建一个单线程。在MyThread类的run()函数可以编写实际的线程工作任务。通过workerThread.start()启动线程,在线程开始执行时,会自动调用MyThread类对象的run()函数

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值