QT——如何在不同线程中对同一个UI界面进行操作

最近在做一个界面,这个界面的功能有两个:

(1)点击开始按钮,进入循环,等待设备插入;

(2)点击停止按钮,中止等待过程。

对于“开始”按钮,很自然的就写了个while,在循环里等待设备插入。但是这就出现一个问题:这个线程就直接陷进了while里,就是说点击“取消”没有反应了。

为了解决这个问题,我创建了一个线程,使整个循环过程在这个新开的线程里完成(这里记作线程1),而原线程则等待取消按钮按下(记作线程2)。

这又产生了一个新的问题,在循环过程中,我怎么输出我的提示信息?

一开始我的想法是直接在这个新开的线程里(线程1),调用界面的信息提示框(这个组件属于线程2)。

void MainWindow::on_pushButton_clicked()
{
    pthread_create(&moving_thread, NULL, a, (void *)this);
    //创建线程,把当前界面的指针当作参数传入
}
void* MainWindow::a(void* arg)
{
    MainWindow *pointer = (MainWindow *)arg;
    pointer->run(arg);//在run里我用arg指针访问了UI的组件,运行时提示段错误
}

后来查资料知道,线程之间共享的是堆、栈、全局变量、静态变量、函数(C++中的静态成员函数是肯定共享的,非静态成员函数不知道)等,而非静态、非全局变量是不共享的,线程2中的信息提示框正好是非静态、非全局的,因此即使线程1使用指向这界面的指针访问信息提示框,只要不是在线程2中访问这个属于线程2的组件,就会发生段错误。

 

接着,我想到了QT的信号与槽的机制:

(1)在线程1中,在需要显示信息时发送“信息栏显示”信号;

(2)线程2接收该信号,在信息提示框中显示信息;

(3)按下取消按钮,线程2发出“结束"信号;

(4)线程1接收信号,结束本线程。

而这里有个问题,信号与槽该怎么连接?准确来说,是哪个对象的信号连接到哪个对象的槽?

首先,我试着在线程1中,在connect里填了两个this指针:

void* MainWindow::a(void* arg)
{
    MainWindow *pointer = new MainWindow;
    pointer->run(arg);
}
void MainWindow::run(void* arg)
{
    connect(this,SIGNAL(message()),
            this,SLOT(get()));
}    

发现线程2中的信息栏没有任何变化,思考后发现是this指针指向线程1的对象,所以这个connect是把这个新的MainWindow实例里的信号和槽连起来了。我想要的,应该是线程1中的信号,连接到线程2中的槽。因此,作以下改动:

connect(this,SIGNAL(message()),
                (MainWindow *)arg,SLOT(get()));

修改后可实现预期效果。

另外发现,虽然在线程(线程1)中不能直接访问另一个线程(线程2)的局部变量,但是如果获得了线程2的指针,在线程1是可以用这个指针调用成员函数的,而且这种方法调用的成员函数可以访问线程2的变量。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值