第84课 多线程与界面组件的通信(上)

1. 有趣的问题:

【编程实验】是否可以在子线程中创建界面组件

//TestThread.h

#ifndef TESTTHREAD_H
#define TESTTHREAD_H

#include <QThread>

class TestThread : public QThread
{
    Q_OBJECT

protected:
    void run();
public:
    explicit TestThread(QObject* parent = 0);
};

#endif // TESTTHREAD_H

//TestThread.cpp

#include "TestThread.h"
#include <QWidget>

TestThread::TestThread(QObject *parent) : QThread(parent)
{

}
void TestThread::run()
{
    QWidget w;  //错误!不能在子线程中创建GUI元素
    w.show();
    exec();
}

//Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();
};

#endif // WIDGET_H

//Widget.cpp

#include "Widget.h"
#include "TestThread.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    TestThread* ptt = new TestThread();
    ptt->start();
}

Widget::~Widget()
{

}

//main.cpp

#include "Widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}
/*出错信息:
ASSERT failure in QWidget: "Widgets must be created in the GUI thread."
*/

2. GUI系统设计原则

(1)所有界面组件的操作只能在主线程中完成;因此,主线程也叫做UI线程

(2)子线程通过信号和槽机制通知界面组件进行更新

3. 多线程与界面组件通信的解决方案

(1)在子线程类定义界面组件更新的信号(如,updateUI)

(2)在主窗口类中定义更新界面组件的槽函数(如,setInfo)

(3)使用异步的队列方式连接更新信号到槽(updateUI→setInfo)

  ①子线程通过发射信号的方式更新界面组件;

  ②所有的界面组件对象只能依附于主线程

【编程实验】子线程中更新界面组件

//UpdateThread.h

#ifndef UPDATETHREAD_H
#define UPDATETHREAD_H

#include <QThread>

class UpdateThread : public QThread
{
    Q_OBJECT
protected:
    void run();
public:
    explicit UpdateThread(QObject* parent = 0);

signals:
    void updateUI(QString text);
};

#endif // UPDATETHREAD_H

//UpdateThread.cpp

#include "UpdateThread.h"

UpdateThread::UpdateThread(QObject *parent) : QThread(parent)
{
}

void UpdateThread::run()
{
    emit updateUI("Begin"); //通知UI线程更新

    for(int i=0; i<10; i++){
        emit updateUI(QString::number(i));

        sleep(1);
    }

    emit updateUI("End");
}

//Widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include <QPlainTextEdit>
#include <QWidget>
#include "UpdateThread.h"

class Widget : public QWidget
{
    Q_OBJECT
    UpdateThread m_thread;
    QPlainTextEdit textEdit;
protected slots:
    void appendText(QString text);
public:
    Widget(QWidget *parent = 0);
    ~Widget();
};

#endif // WIDGET_H

//Widget.cpp

#include "Widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    textEdit.setParent(this);
    textEdit.move(20, 20);
    textEdit.resize(200, 150);
    textEdit.setReadOnly(true);

    connect(&m_thread, SIGNAL(updateUI(QString)), this, SLOT(appendText(QString)));

    m_thread.start();
}

void Widget::appendText(QString text)
{
    textEdit.appendPlainText(text);
}

Widget::~Widget()
{

}

//main.cpp

#include "Widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

4. 小结

(1)现代GUI平台只允许在主线程中直接操作界面组件

(2)Qt中可以借助信号与槽机制在子线程中操作界面组件

(3)进行信号和槽连接必须采用异步的队列连接方式

(4)界面组件对象只能依附于主线程

时间: 2024-08-26 02:43:04

第84课 多线程与界面组件的通信(上)的相关文章

[备忘]不用许可证 多线程直接操作界面组件比如超级列表框的实现

平时多线程来操作界面组件 同时写入或者修改数据  比如常见的把多个线程都把日志同时写入到编辑框 又或者 多个线程同时的修改一个超级列表框上的线程状态和其他信息 这样会出现一个问题 如何避免多个线程同时操作一个组件导致的组件冲突问题 我们常用的是使用许可证来给每个线程规定访问顺序来依次执行 不过这样的调整的确从效率上说很低下 大漠老师使用 发送消息 或者说是使用window消息机制来实现不加许可证的同时修改界面组件的思路非常好 511遇见老师也对这个思路进行了深度解析 已经非常的详细了http:/

没事抽空学——常用界面组件属性

android:latout_width fill_parent 设置组件宽高,fill和wrap相同 match_parent wrap_content android:text 组件中文字 组件中文字 android:ems 数值和长度单位 英文字M的数倍 android:inputType text/number/date/time... 文字类型 android:background example:ff0000 6或6十六位进制数设置底色 android:textSize 数值 设置文

Android 自学之基本界面组件(下)

按钮(Button)与图片按钮(ImageButton)组件的功能和用法 Button继承了TextView,ImageButton继承了Button.不管是Button还是ImageButton,他们的功能都很单一,主要是在UI界面生成一个按钮,该按钮可以供用户单击,当用户单击按钮后出发一个Onclick事件. Button  和  ImageButton的不同在于Button生成的按钮显示文字,ImageButton生成的按钮显示图片.(关于ImageButton属性android:text

Swing界面组件的通用属性

----------------siwuxie095 Swing 界面组件(控件)的通用属性: (1)enabled:启用/禁用某组件(控件) 「某些 Container 也有这个选项,如果将其 enabled 设为 false, 则该 Container 里的组件(控件)依然可用」 (2)foreground:前景色 「所有组件(控件)前景色的设定,某些组件(控件)的前景色应用于文本(text)」 (3)background:背景色 「某些组件(控件)设置背景色后并不会生效,需要到 高级属性

c# winform编程之多线程ui界面资源修改总结篇

单线程的winfom程序中,设置一个控件的值是很easy的事情,直接 this.TextBox1.value = "Hello World!";就搞定了,但是如果在一个新线程中这么做,比如: private void btnSet_Click(object sender, EventArgs e) {        Thread t = new Thread(new ParameterizedThreadStart(SetTextBoxValue));     //当然也可以用匿名委托

1.1.1. 常用界面组件使用

1.1.1. 常用界面组件使用 功能 代码参考 {{属性名}} 数据绑定对象,例如{{attr1}}这里会自动绑定控制层$scope.attr1.此标签可以出现在页面调用的js函数中,注意不能使用双引号和单引号了,如<a ng-click="gotoDetail({{item.planserialno}})">立即投资</a> ng-click 标签的点击事件,<a ng-click="testService()">test<

CCS界面组件

概述 这里的界面组件是HTML提供的常见用户界面的统称 导航菜单 菜单由一组链接组成,为了使链接具有层次结构,我们用ul或ol来分组和管理链接元素 纵向菜单制作 下面是仿百度首页的HTML标签 1 <nav class="list1"> 2 <ul> <!--无序列表--> 3 <li><a href="#">新闻</a></li> <!--# 是占位符,用于将来替换成实际UR

ionic入门之色彩、图标、边距和界面组件:列表

转载声明,本文章来自http://cnodejs.org/topic/551b516c33e515e67640631e 目录: 色彩.图标和边距 色彩 图标 内边距 界面组件:列表 列表:.list 成员容器:.item .item: 嵌入文本 .item : 嵌入图标 .item : 嵌入头像 .item : 嵌入缩略图 .item : 嵌入大图 色彩 ionic定义了九种前景/背景/边框的色彩样式,: 可以在任何元素上使用这些样式设置前景和背景颜色: <any class="posit

实验十四 Swing图形界面组件

实验十四  Swing图形界面组件 实验时间 20178-11-29 1.实验目的与要求 (1) 掌握GUI布局管理器用法: (2) 掌握各类Java Swing组件用途及常用API: 2.实验内容和步骤 实验1: 导入第12章示例程序,测试程序并进行组内讨论. 测试程序1 在elipse IDE中运行教材479页程序12-1,结合运行结果理解程序: 掌握各种布局管理器的用法: 理解GUI界面中事件处理技术的用途. 在布局管理应用代码处添加注释: 测试结果: 这个程序是一个网格布局,网格布局像一