怎么用QT新建一个这样的项目呢关键代码:the voidd Widget::on_pushButton_clicked(){ Q

酷勤网 C 程序员的那点事!
当前位置: >
浏览次数:次
问题的由来
心血来潮,想利用QTimer 配合setWindowOpacity()方法来实现一个窗体淡入的效果。
粗糙的实验代码:
voidWidget::on_pushButton_clicked()
QTimer*timerOpacity=newQTimer(this);
connect(timerOpacity,SIGNAL(timeout()),this,SLOT(changeOpacity()));
timerOpacity-&start(100);
voidWidget::changeOpacity()
if(opalevel&8)
doubleopacity[9]={0.9,0.8,0.7,0.6,0.5,0.4,0.3,0.2,0.1};
ui-&stackedWidget-&setWindowOpacity(opacity[opalevel]);
ui-&widget-&setWindowOpacity(opacity[opalevel]);
this-&setWindowOpacity(opacity[opalevel]);
qDebug()&&&opalevel=&&&opalevel&&&ui-&widgetopacity:&&&ui-&widget-&windowOpacity();
qDebug()&&&opalevel=&&&opalevel&&&ui-&stackedWidgetopacity:&&&ui-&stackedWidget-&windowOpacity();
qDebug()&&&opalevel=&&&opalevel&&&uiopacity:&&&this-&windowOpacity()&&
void Widget::on_pushButton_clicked()
QTimer *timerOpacity = new QTimer(this);
connect(timerOpacity,SIGNAL(timeout()),this,SLOT(changeOpacity()));
timerOpacity-&start(100);
void Widget::changeOpacity()
if (opalevel & 8)
double opacity[9] ={0.9,0.8,0.7,0.6,0.5,0.4,0.3,0.2,0.1};
ui-&stackedWidget-&setWindowOpacity(opacity[opalevel]);
ui-&widget-&setWindowOpacity(opacity[opalevel]);
this-&setWindowOpacity(opacity[opalevel]);
qDebug()&&&opalevel = &&& opalevel &&& ui-&widget opacity:&&&ui-&widget-&windowOpacity();
qDebug()&&&opalevel = &&& opalevel &&& ui-&stackedWidget opacity:&&&ui-&stackedWidget-&windowOpacity();
qDebug()&&&opalevel = &&& opalevel &&& ui opacity : &&& this-&windowOpacity()&&
现象是主窗体的有淡入的效果,即透明度有变化,但是子窗体没有,opacity始终为1。
opalevel =0ui-&widget opacity: 1
opalevel =0ui-&stackedWidget opacity: 1
opalevel =0ui opacity0.898039
opalevel =8ui-&widget opacity: 1
opalevel =8ui-&stackedWidget opacity: 1
opalevel =8ui opacity0.0980392
voidQWidget::setWindowOpacity(qrealopacity)
Q_D(QWidget);
if(!isWindow())
void QWidget::setWindowOpacity(qreal opacity)
Q_D(QWidget);
if (!isWindow())
QGraphicsOpacityEffect
//intheconstructor
opacityEffect=newQGraphicsOpacityE
ui-&widget-&setGraphicsEffect(opacityEffect);
//inchangeOpacity()
opacityEffect-&setOpacity(opacity[opalevel]);
// in the constructor
opacityEffect = new QGraphicsOpacityE
ui-&widget-&setGraphicsEffect(opacityEffect);
// in changeOpacity()
opacityEffect-&setOpacity(opacity[opalevel]);
& 相关主题:
本文来源:后使用快捷导航没有帐号?
您尚未登录,请登录后浏览更多内容!
查看: 9664|回复: 6
在线时间382 小时帖子精华4Qter豆3028 贡献143 毅力537 注册时间最后登录
Qter豆3028
版权声明该文章原创于Qter开源社区(),作者yafeilinux,转载请注明出处!
在前面的内容中已经多次用到过信号和槽了,这一节我们将详细讲解信号和槽的机制和使用方式。大家可以在帮助中查看Signals& Slots关键字。
环境:Windows Xp + Qt 4.8.5+QtCreator2.8.0
一、信号和槽机制二、信号和槽的自动关联三、信号和槽的高级应用
一、信号和槽机制
信号和槽用于两个对象之间的通信,信号和槽机制是Qt的核心特征,也是Qt不同于其他开发框架的最突出的特征。在GUI编程中,当改变了一个部件时,总希望其他部件也能了解到该变化。更一般来说,我们希望任何对象都可以和其他对象进行通信。例如,如果用户点击了关闭按钮,我们希望可以执行窗口的close()函数来关闭窗口。为了实现对象间的通信,一些工具包中使用了回调(callback)机制,而在Qt中,使用了信号和槽来进行对象间的通信。当一个特殊的事情发生时便可以发射一个信号,比如按钮被单击;而槽就是一个函数,它在信号发射后被调用,来响应这个信号。在Qt的部件类中已经定义了一些信号和槽,但是更多的做法是子类化这个部件,然后添加自己的信号和槽来实现想要的功能。& && & 在前面使用过的信号和槽的关联,都是一个信号对应一个槽。其实,一个信号可以关联到多个槽上,多个信号也可以关联到同一个槽上,甚至,一个信号还可以关联到另一个信号上,如下图所示。如果存在多个槽与某个信号相关联,那么,当这个信号被发射时,这些槽将会一个接一个地执行,但是它们执行的顺序是随机的,无法指定它们的执行顺序。
下面通过一个简单的例子来进一步讲解信号和槽的相关知识。这个例子实现的效果是:在主界面中创建一个对话框,在这个对话框中可以输入数值,当按下确定按钮时关闭对话框并且将输入的数值通过信号发射出去,而在主界面中接收该信号并且显示数值。新建Qt Gui应用,项目名称为“mySignalSlot”,基类选择QWidget,然后类名保持“Widget”不变。项目建立完成后,向项目中添加新文件,模板选择Qt分类中的“Qt设计师界面类”,界面模板选择“Dialog without Buttons”,类名为“MyDialog”。完成后首先在mydialog.h文件中添加代码来声明一个信号:
signals:& & void dlgReturn(int);& && && && && && &// 自定义的信号
& && & 声明一个信号要使用signals关键字,在signals前面不能使用public、private和protected等限定符,因为只有定义该信号的类及其子类才可以发射该信号。而且信号只用声明,不需要也不能对它进行定义实现。还要注意,信号没有返回值,只能是void类型的。因为只有QObject类及其子类派生的类才能使用信号和槽机制,这里的MyDialog类继承自QDialog类,QDialog类又继承自QWidget类,QWidget类是QObject类的子类,所以这里可以使用信号和槽。不过,使用信号和槽,还必须在类声明的最开始处添加Q_OBJECT宏,在这个程序中,类的声明是自动生成的,已经添加了这个宏。
在mydialog.ui对应的界面中添加一个Spin Box部件和一个Push Button部件,将pushButton的显示文本改为“确定”。然后转到pushButton的单击信号clicked()槽,更改如下:
void MyDialog::on_pushButton_clicked()& &// 确定按钮{& &int value = ui-&spinBox-&value();& & // 获取输入的数值& &emit dlgReturn(value);& && && && && &// 发射信号& &close();& && && && && && && && && &&&// 关闭对话框}
& && & 当单击确定按钮时,便获取spinBox部件中的数值,然后使用自定义的信号将其作为参数发射出去。发射一个信号要使用emit关键字,例如程序中发射了dlgReturn()信号。& && & 然后到widget.h文件中添加自定义槽的声明:
private slots:& & void showValue(int value);
& && & 声明一个槽需要使用slots关键字。一个槽可以是private、public或者protected类型的,槽也可以被声明为虚函数,这与普通的成员函数是一样的,也可以像调用一个普通函数一样来调用槽。槽的最大特点就是可以和信号关联。下面打开widget.ui文件,向界面上拖入一个Label部件,然后更改其文本为“获取的值是:”。然后进入widget.cpp文件中添加头文件#include &mydialog.h&,再在构造函数中添加代码:
MyDialog *dlg = new MyDialog(this); // 将对话框中的自定义信号与主界面中的自定义槽进行关联connect(dlg,SIGNAL(dlgReturn(int)),this,SLOT(showValue(int)));dlg-&show();
& && & 这里创建了一个MyDialog,并且使用Widget作为父部件。然后将MyDialog类的dlgReturn()信号与Widget类的showValue()槽进行关联。信号和槽进行关联,使用的是QObject类的connect()函数,这个函数的原型如下:
bool QObject::connect ( const QObject *sender, const char * signal, const QObject * receiver, const char * method,Qt::ConnectionType type = Qt::AutoConnection )
它的第一个参数为发送信号的对象,例如这里的dlg;第二个参数是要发送的信号,这里是SIGNAL(dlgReturn(int));第三个参数是接收信号的对象,这里是this,表明是本部件,即Widget,当这个参数为this时,也可以将这个参数省略掉,因为connect()函数还有另外一个重载形式,该参数默认为this;第四个参数是要执行的槽,这里是SLOT(showValue(int))。对于信号和槽,必须使用SIGNAL()和SLOT()宏,它们可以将其参数转化为const char* 类型。connect()函数的返回值为bool类型,当关联成功时返回true。还要注意,在调用这个函数时信号和槽的参数只能有类型,不能有变量,例如写成SLOT(showValue(int value))是不对的。对于信号和槽的参数问题,基本原则是信号中的参数类型要和槽中的参数类型相对应,而且信号中的参数可以多于槽中的参数,但是不能反过来,如果信号中有多余的参数,那么它们将被忽略。下面介绍一下connect()函数的最后一个参数,它表明了关联的方式,其默认值是Qt::AutoConnection,这里还有其他几个选择,在编程中一般使用默认值,例如这里,在MyDialog类中使用emit发射了信号之后,就会执行槽,只有等槽执行完了以后,才会执行emit语句后面的代码。大家也可以将这个参数改为Qt::QueuedConnection,这样在执行完emit语句后便会立即执行其后面的代码,而不管槽是否已经执行。当不再使用这个关联时,还可以使用disconnect()函数来断开关联。
下面是自定义槽的实现,在这里只是简单的将参数传递来的数值显示在了标签上。因为这里使用了中文,所以大家记着在main.cpp文件中添加相关代码。
void Widget::showValue(int value)& && && &// 自定义槽{& &ui-&label-&setText(tr(&获取的值是:%1&).arg(value));}
& && & 现在大家可以运行一下程序查看效果。如下图所示。
这个程序中自定义了信号和槽,可以看到它们的使用是很简单的,只需要对它们进行关联,然后在适当的时候发射信号就行。下面列举一下使用信号和槽应该注意的几点:
需要继承自QObject或其子类;在类声明的最开始处添加Q_OBJECT宏;槽中的参数的类型要和信号的参数的类型相对应,且不能比信号的参数多;信号只用声明,没有定义,且返回值为void类型。
二、信号和槽的自动关联
信号和槽还有一种自动关联方式,例如前面程序中在设计模式直接生成的按钮的单击信号的槽,就是使用的这种方式:on_pushButton_clicked(),它由“on”、部件的objectName和信号三部分组成,中间用下划线隔开。这样组织的名称的槽就可以直接和信号关联,而不用再使用connect()函数。不过使用这种方式还要进行其他设置,而前面之所以可以直接使用,是因为程序中默认已经进行了设置。下面来看一个简单的例子。
& && & 新建Qt Gui应用,项目名称为“mySignalSlot2”,基类选择QWidget,然后类名保持“Widget”不变。完成后先在widget.h文件中进行函数声明:
private slots:& & void on_myButton_clicked();
这里自定义了一个槽,它使用自动关联。然后在widget.cpp文件中添加头文件#include &QPushButton&,再将构造函数的内容更改如下:
Widget::Widget(QWidget *parent) :& &QWidget(parent),& &ui(new Ui::Widget){& &QPushButton *button = new QPushButton(this); // 创建按钮& &button-&setObjectName(&myButton&);& && && &&&// 指定按钮的对象名& &ui-&setupUi(this);& && && && && && && & //要在定义了部件以后再调用这个函数}
& && & 因为在setupUi()函数中调用了connectSlotsByName()函数,所以要使用自动关联的部件的定义都要放在setupUi()函数之前,而且还必须使用setObjectName()函数指定它们的objectName,只有这样才能正常使用自动关联。下面是槽的定义:
void Widget::on_myButton_clicked()& && && & // 使用自动关联{& &close();}
& && & 这里进行了关闭部件的操作。对于槽的函数名,中间要使用前面指定的objectName,这里是“myButton”。现在运行一下程序,单击按钮,发现可以正常关闭窗口。
& && & 可以看到,如果要使用信号和槽的自动关联,就必须在connectSlotsByName()函数之前进行部件的定义,而且还要指定部件的objectName。鉴于这些约束,虽然自动关联形式上很简单,但是实际编写代码时却很少使用。而且,在定义一个部件时,很希望明确的使用connect()函数来对其进行信号和槽的关联,这样当别人看到这个部件定义时,就可以知道和它相关的信号和槽的关联了。而使用自动关联,却没有这么明了。
三、信号和槽的高级应用
& && & 有时我们希望获得信号发送者的信息,在Qt中提供了QObject::sender()函数来返回发送该信号的对象的指针。但是如果有多个信号关联到了同一个槽上,而在该槽中需要对每一个信号进行不同的处理,使用上面的方法就很麻烦了。对于这种情况,便可以使用QSignalMapper类。QSignalMapper可以被叫做信号映射器,它可以实现对多个相同部件的相同信号进行映射,为其添加字符串或者数值参数,然后再发射出去。对于这个类的使用,大家可以参考的1.3.3小节,那里有这个类的实际应用。还有就是Qt的演示程序中的Tools分类下的Input Panel示例程序中也使用了这个类,大家也可以参考一下这个程序。在这里便不再详细讲述这个类的使用了。
& && & 在本节的最后,来看一下信号和槽机制的特色和优越性:
信号和槽机制是类型安全的,相关联的信号和槽的参数必须匹配;信号和槽是松耦合的,信号发送者不知道也不需要知道接受者的信息;信号和槽可以使用任意类型的任意数量的参数。
虽然信号和槽机制提供了高度的灵活性,但就其性能而言,还是慢于回调机制的。当然,这点性能差异通常在一个应用程序中是很难体现出来的。
涉及到的代码:
上一篇:& &
下一篇:& &
返回: & &
本帖子中包含更多资源
才可以下载或查看,没有帐号?
在线时间6 小时帖子精华0Qter豆60 贡献20 毅力21 注册时间最后登录
Qter1级会员, 积分 41, 距离下一级还需 59 积分
感觉connectSlotByName可以使用自定义的信号啊,代码如下:
class MyObject : public QObject
& & Q_OBJECT
& & explicit MyObject(QObject *parent = 0);
& & void signalTest();
public slots:
& & void on_MyObject_signalTest();
& & void on_Object_otherSignal();
& & Object *
MyObject::MyObject(QObject *parent) :
& & QObject(parent)
& & setObjectName(&MyObject&);
& & qDebug() && this-&objectName();
& & QMetaObject::connectSlotsByName(this);
& & emit signalTest();
& & qDebug() && &===============&;
& & obj = new Object();
& & emit obj-&otherSignal();
void MyObject:n_MyObject_signalTest()
& & qDebug() && &Signal Auto Conn Succ!&;
void MyObject:n_Object_otherSignal()
& & qDebug() && &Signal Other Conn Succ!&;
运行OK,void MyObject:n_MyObject_signalTest()可以打印出来,但是void MyObject:n_Object_otherSignal()运行失败
在线时间382 小时帖子精华4Qter豆3028 贡献143 毅力537 注册时间最后登录
Qter豆3028
chenlong12580 发表于
感觉connectSlotByName可以使用自定义的信号啊,代码如下:
class MyObject : public QObject
嗯,是的,可以使用自定义信号的。教程中内容已经修改。
在线时间6 小时帖子精华0Qter豆60 贡献20 毅力21 注册时间最后登录
Qter1级会员, 积分 41, 距离下一级还需 59 积分
yafeilinux 发表于
嗯,是的,可以使用自定义信号的。教程中内容已经修改。
你好,但是我又遇到了一个问题,上面的代码中,我做了两个试验都是关于信号-槽的自动绑定的。第一个实验是自定义信号和槽在同一个类中,可以成功!第二个实验是自定义信号和槽分别在两个类中(代码上面的回复也有),这个时候不能成功,请问你知道原因吗?
在线时间382 小时帖子精华4Qter豆3028 贡献143 毅力537 注册时间最后登录
Qter豆3028
chenlong12580 发表于
你好,但是我又遇到了一个问题,上面的代码中,我做了两个试验都是关于信号-槽的自动绑定的。第一个实验 ...
可以使用该类已有的信号试试。
自动关联一般是设计器上的部件才用的,可以研究一下,不过实际编程中用的不多。
在线时间7 小时帖子精华0Qter豆31 贡献10 毅力11 注册时间最后登录
Qter1级会员, 积分 21, 距离下一级还需 79 积分
为什么我运行的程序,第一个汉字“确定”正常,第二个“获取的值是:”显示是乱码呢?
在线时间382 小时帖子精华4Qter豆3028 贡献143 毅力537 注册时间最后登录
Qter豆3028
zhugeqiangren 发表于
为什么我运行的程序,第一个汉字“确定”正常,第二个“获取的值是:”显示是乱码呢? ...
你用什么版本的Qt,应该是编码问题
注册账号后积极上传头像的会员
坚持登陆,持之以恒!
积极发帖的会员
Powered by
X2.5. Theme By二次元同好交流新大陆
扫码下载App
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
阅读(5093)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_',
blogTitle:'qt
接口(最全)',
blogAbstract:'/*****************Qt显示中文(主要在main函数实现)***************************/&#include &QTextCodec&&& // 编码头文件&QTextCodec::setCodecForCStrings(QTextCodec::codecForName(\"gb18030\")); // 窗口里面可以接收或写中文文字&// 这个和上面那个是等级的 QTextCodec::setCodecForLocale(QTextCodec::codecForName(\"gb18030\"));&QTextCodec::setCodecForTr(QTextCodec::codecForName(\"gb18030\")); // 窗口部件里(如button)可以中文显示 &',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:0,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list} 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
Qt用户界面设计
下载积分:840
内容提示:精心收集的各类精品文档,值得下载: Qt用户界面设计
文档格式:PPT|
浏览次数:967|
上传日期: 11:59:09|
文档星级:
该用户还上传了这些文档
Qt用户界面设计
官方公共微信在QT中,我在图形界面里面加了一个pushbutton按钮,我想在按了这个按钮之后执行相应的代码,应该怎么做?_百度知道
在QT中,我在图形界面里面加了一个pushbutton按钮,我想在按了这个按钮之后执行相应的代码,应该怎么做?
提问者采纳
要注意的是这个objectName不是你按钮上显示的文本.,如果你给按钮起了别的名字.,这里就显示你起的名字,点OK:.:on_pushButton_clicked()处,选中clicked(),on_pushbutton_clicked()中的pushbutton是你的按钮的objectName。然后就跳转到代码编写界面的类似void Widget,这里的Widget是你的窗口类的类名在按钮上右键,转到槽
提问者评价
其他类似问题
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁

我要回帖

更多关于 void(0) 的文章

 

随机推荐