文章目录
- 前言
- 一、信号和槽
- 二、控件
- 总结
前言
软件:Qt Creator 4.10
QT是做UI的,主要做PC的UI界面
特点:
1.跨平台(windows linux macos..) 2.开源
3.面向对象的,使用C++开发,执行效率高。
(qt 改进了C++)提供了全套的方法: UI 进程 线程 文件 数据 网络...
一、信号和槽
信号和槽:QT 特有的信号传输机制,用于对象之间的通信
信号signal:对象因为某种事件发出信号
槽slot :信号的接收者,处理信号的对象
一个信号可以发送给多个接收者,一个接收者可以接受多个信号
发送者发送信号---->接受者收到信号后,使用槽函数来处理信号
#include "widget.h"
#include "ui_widget.h"
#include "signalslot.h"
Widget::Widget(QWidget *parent)
: QWidget(parent) //执行父亲背景
, ui(new Ui::Widget) //创建ui对象:用户所有控件
{
ui->setupUi(this); //生成用户的拖拽
ui->btnSure->setText("sure");
/*
这里你可以写 操作UI的代码
this指向当前对象,就是 main{ Widget w;}
this->ui
*/
ui->lineEdit->setText("hello world");
/*信号和槽的演示,实现两个类(发送和接收类) */
class sender snd;
class receiver recv;
//绑定了,当发送者发送指定信号的时候, qt会自动寻找接受者,并调用接收者的槽函数
connect(&snd, SIGNAL( signal_snd(void) ) ,&recv, SLOT( slot_handle(void) ) );
connect(&snd, SIGNAL( signal_snddata(int) ) ,&recv, SLOT( slot_handle_int(int) ) );
connect(&snd, SIGNAL( signal_sndString(QString)),&recv,SLOT(slot_handle_string(QString)) );
/*如何发送信号呢
emit 发送者对象.信号函数();
*/
emit snd.signal_snd(); /* 接受者对象recv的slot_handle被执行. */
emit snd.signal_snddata(56);
emit snd.signal_sndString("hello world");
}
Widget::~Widget()
{
delete ui;
}
#ifndef SIGNALSLOT_H
#define SIGNALSLOT_H
/*
信号和槽,需要qt提供支持
如何让类支持 信号和槽,
1.你的class 要继承 QObject类---qt的基类:1.实现了信号和槽 2.
当然你要包含他的头文件 #include <QObject>
2.添加qt对C++的扩展
在你的类中添加 宏 Q_OBJECT
*/
/*
发送者,要发送信号
信号,是一个特殊的函数
如何实现信号函数:
*/
#include <QObject>
class sender :public QObject{
Q_OBJECT
public:
sender();
private:
signals: //关键字,说明下面的都是 信号函数
void signal_snd(void); //信号,从来不需要##实现##的. 没有数据传递的
void signal_snddata(int); //信号,传递一个整数给对方
void signal_sndString(QString); //信号没有返回值
};
class receiver:public QObject{
Q_OBJECT
public:
receiver();
private:
public slots: //关键字,声明下面的函数 是slot函数,专门用来处理信号的
void slot_handle(void); //slot 函数,专门用于处理 接收到的信号的,必须有实现
void slot_handle_int(int); //slot函数 ,绑定了发送者的 void signal_snddata(int);
void slot_handle_string(QString);
};
#endif // SIGNALSLOT_H
#include "signalslot.h"
#include <qDebug>
sender::sender() {}
receiver::receiver() {}
void receiver::slot_handle()
{
qDebug()<<"in slot_handle(void)"<<endl;
}
void receiver::slot_handle_int(int val)
{
qDebug()<<"in slot_handle_int(int) "<<val<<endl;
}
void receiver::slot_handle_string(QString str)
{
qDebug()<<"in slot_handle_string(QString) "<<str<<endl;
}
效果展示:
二、控件
1.按钮 QPushbutton
信号: clicked() ---点击鼠标弹起的时候触发信号
pressed()---mouse press down
release()---鼠标释放的时候,和clicked一样
显示:
setText( QString txt)
setEnable(bool,show) // 0/1
手工UI :
首先创建一个QPushbutton 对象,让对象显示在背景上
下面是代码,我把头文件和函数放在一起了,并让信号(点击、释放、按压)和槽函数建立连接
// 头文件里面的槽函数
/*
public slots:
void btnLogClickedSlotFun();
void btnLogpressedSlotFun();
void btnLogreleasedSlotFun();
void btnEnableSlotFun();
*/
//########### you code ############
ui->btnlog->setText("Sure");
connect(ui->btnlog,SIGNAL(clicked()),this,SLOT(btnLogClickedSlotFun()));
connect(ui->btnlog,SIGNAL(pressed()),this,SLOT(btnLogpressedSlotFun() ));
connect(ui->btnlog,SIGNAL(released()),this,SLOT(btnLogreleasedSlotFun() ));
connect(ui->btnEnable,SIGNAL(clicked()),this,SLOT(btnEnableSlotFun() ));
connect(ui->btn1,SIGNAL(clicked()),this,SLOT(btn1Btnlog1SlotFun()));
connect(ui->btn2,SIGNAL(clicked()),this,SLOT(btn2Btnlog2SlotFun()));
// ########### manual--手工的 UI######
ptStart = new QPushButton;
ptStart->setParent(this); //设置父对象
//ptStart->setGeometry(int x,int y,int widht,int height);
ptStart->setGeometry(30,40,80,60);
ptStart->setText("munnul");
//ptStart->show(); 可以不写,父对象在显示的时候,
connect(ptStart,SIGNAL(clicked()), this,SLOT( btnManualuiSlotFun() ));
void Widget::btnLogClickedSlotFun()
{
//__func__LINE__,分别是两个宏,编译器 遇到他们分别替换为 当前所在的函数和 行号
qDebug()<<__func__<<__LINE__<<endl;
}
void Widget::btnLogpressedSlotFun()
{
qDebug()<<__func__<<__LINE__<<endl;
}
void Widget::btnLogreleasedSlotFun()
{
qDebug()<<__func__<<__LINE__<<endl;
}
void Widget::btnEnableSlotFun()
{
qDebug()<<__func__<<__LINE__<<endl;
static int cnt=0;
cnt++;
if(cnt%2==1){
ui->btnlog->setEnabled(false);
}else{
ui->btnlog->setEnabled(true);
}
}
void Widget::btnManualuiSlotFun()
{
qDebug()<<"hello"<<endl;
}
效果展示:
2.标签 QLabel
显示文本/图片,使用者不能修改内容
显示: setText( QString name);
显示图片:
qt创建资源管理器,把图片加入该资源source,每张图片都有一个内部路径
然后添加图片文件
定义png图像 对象,指定源文件图片
QPixmap pix("图片对象路径");
.setPixmap(QPixmap &pix), 给label 设定要显示的图像
.setScaledContends(bool); 是否允许内容缩放
代码展示:
//########### 设置 lable显示内容#######
ui->labelName->setText("username");
QString str = ui->labelName->text(); //显示lable内容
qDebug()<<"get lable text:"<< str<<endl;
QString strshow = "123454344-=dsls dkklakfkjkdjn你好sjkdsjkdjfjkdjfkdfjkdfdkfgkkkffjjj";
ui->labelName->setWordWrap(true); //根据文本内容,调整显示,换行
ui->labelName->setText(strshow);
/*
1.定义png图像对象,指定源文件图片
2.lable设置要显示的图片
根据情况,是否允许缩放内容
*/
QPixmap pix(":/rs/Weather 512x512.png"); //:表示是qt 内部路径
ui->labelimage->setPixmap(pix);
// 允许lable 里面的内容缩放 scale--缩放 content-内容
ui->labelimage->setScaledContents(true);
//手工写代码
// ptLblManual = new QLabel(this); ptLblManual->setParent(this);
ptLblManual = new QLabel(this);
ptLblManual->setGeometry(20,300,200,200); //x,y ,width,height
QPixmap pixManual(":/rs/Mail 512x512.png");
ptLblManual->setPixmap(pixManual);
ptLblManual->setScaledContents(true);
效果展示:
3.输入框 QLineEdit--行输入框 QTextLEdit ---多行输入框
QLineEdit:
显示: 默认填充
setText() 设置内容
显示有两种方式,一种是明文显示(默认),一种是密文显示
setEchoMode(QLineEdit :: Password); //以㊙文显示
QString.text(Qstring) 代码中获取用户输入
setPlaceholderText(); 设置占坑文本
信号: 输入完成信号
editFinish() 当用户正在编辑,突然回车或者鼠标点击其他地方(失去焦点),
表示输入完毕
textChanged(QString &) 只要文本改变就触发信号(每改变)
QTextEdit:
设置文本: setText( QString );
获取文本: QString toplainText();
清空文本:clear(); 追加文本: append( QString txt);
//########## log btn slot fun,handle lineEdit
connect(ui->btnlog,SIGNAL(clicked()) ,this, SLOT( btnLogClickedSlotFun() ));
//默认填充
ui->lineEditName->setText("xiaoming");
ui->lineEditPassword->setEchoMode(QLineEdit::Password); //以密文显示
ui->lineEditPassword->setText("123456");
//处理密码输入框的 输入完成信号
connect(ui->lineEditPassword, SIGNAL( editingFinished()) ,this, SLOT( btnEditPasswordFinishedSlotFun() ));
//用户名 输入检测: textChanged 信号处理
connect(ui->lineEditName, SIGNAL( textChanged(const QString&)),\
this,SLOT(lineEditNameTextchangeSlotFun(const QString&) ));
//多行文本###############
connect(ui->btnGet,SIGNAL(clicked()),this,SLOT( btnGetclickedSlotFun() ));
connect(ui->btnSet,SIGNAL(clicked()),this,SLOT( btnSetClickedSlotFun() ));
connect(ui->btnClear,SIGNAL(clicked()),this,SLOT( btnClearClickedSlotFun() ));
connect(ui->btnAppend,SIGNAL(clicked()),this,SLOT( btnAppendSlotFun()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::btnLogClickedSlotFun()
{
qDebug()<<ui->lineEditName->text()<<" "<<ui->lineEditPassword->text()<<endl;
}
void Widget::btnEditPasswordFinishedSlotFun()
{
qDebug()<<__func__<<__LINE__<<endl;
}
void Widget::lineEditNameTextchangeSlotFun(const QString &str)
{
qDebug()<<__func__<<__LINE__<<str <<endl;
QChar ch = str[ str.length() -1 ];
if(ch >='a' && ch <='z' ){
}else {
qDebug()<<"invalid input"<<ch <<endl;
}
}
void Widget::btnSetClickedSlotFun()
{
ui->textEdit->setText("欢迎提供建议....");
}
void Widget::btnGetclickedSlotFun()
{
qDebug()<<"textEdit got:"<<ui->textEdit->toPlainText()<<endl;
}
void Widget::btnClearClickedSlotFun()
{
ui->textEdit->clear();
//ui->textEdit->setText("");
}
void Widget::btnAppendSlotFun()
{
QString strname= ui->lineEditName->text();
//ui->textEdit->append(strname);
//另一种实现
QString strText = ui->textEdit->toPlainText();
QString newStr = strText + "\n" +strname; //strText.operator +( strname)
ui->textEdit->setText(newStr);
}
效果展示:
4.多选框--QCheckBox 单选框---QRadioButton 分组框---QGroupBox
QCheckBox:
信号:
stateChanged(int sel); 当前某个多选按钮改变,发出该信号,信号会包含当前的
状态(被选中--2 未选中--0)
显示:setText( QString);
bool isChecked(); 判断是否被选中 setChecked(bool ); 设置状态
RadioButton:
信号: clicked() 当你点击某个对象,该对象发出被选中信号
显示:同多选框
QGroupBox: 可以让每个单选框独立,互相之间不影响
设置标题 setTitle
代码显示:
//##############复选框 checkBox#########
ui->checkBoxWoman->setText("woman");
ui->checkBoxMoney->setChecked(true);
connect(ui->checkBoxWoman,SIGNAL(stateChanged(int)), this,SLOT( checkBoxCommonStateChangedSlotFun( int) ));
connect(ui->checkBoxMoney,SIGNAL(stateChanged(int)), this,SLOT( checkBoxCommonStateChangedSlotFun( int) ));
connect(ui->checkBoxHouse,SIGNAL(stateChanged(int)), this,SLOT( checkBoxCommonStateChangedSlotFun( int) ));
connect(ui->checkBoxCar,SIGNAL(stateChanged(int)), this,SLOT( checkBoxCommonStateChangedSlotFun( int) ));
//########### 单选框##############
ui->rbtnSexMan->setChecked(true);
ui->rbtnSexWoman->setChecked(true); //只会显示后面一个,前面一个被覆盖
connect(ui->rbtnSexMan,SIGNAL(clicked()), this,SLOT( rbtSexClickedSlotFun() ));
connect(ui->rbtnSexWoman,SIGNAL(clicked()), this,SLOT( rbtSexClickedSlotFun() ));
// manual GroupBox and QRadioBatton 手工创建组合框和单选框
pGrpBox = new QGroupBox(this); //指定父对象
pGrpBox->setTitle("手工 --工作");
pGrpBox->setGeometry(20,220,141,180);
//prbtnIt = new QRadioButton(pGrpBox); prbtnIt->setText("程序员");
prbtnIT = new QRadioButton("程序员",pGrpBox);
prbtnIT->setGeometry(10,40,100,20); //坐标 相对于 父对象,并不是 外面的大窗体
prbtnLawyer = new QRadioButton("律师",pGrpBox);
prbtnLawyer->setGeometry(10,70,100,20);
prbtnTeacher = new QRadioButton("教师",pGrpBox);
prbtnTeacher->setGeometry(10,100,100,20);
prbtnIT->setEnabled(true);
}
Widget::~Widget()
{
delete ui;
}
void Widget::checkBoxCommonStateChangedSlotFun(int )
{
qDebug()<<__func__<<"house:"<<ui->checkBoxHouse->isChecked()<<" money:"<<
ui->checkBoxMoney->isChecked()<<"woman:"<<ui->checkBoxWoman->isChecked()<<"car:"<<ui->checkBoxCar->isChecked()<<endl;
}
void Widget::rbtSexClickedSlotFun()
{
qDebug()<<"man"<<ui->rbtnSexMan->isChecked()<<" woman"<<ui->rbtnSexWoman->isChecked()<<endl;
}
效果显示:
5.组合框/下拉框 QComboBox
QComboBox:
构成:
1.整个下拉框
addItem( itemName); 添加主题
int count(); 获取主题个数
int currentIndex(); 当选选择的是第几个主题
QString itemText(); 当前选择的主题的文本
信号: 当用户选择某个主题,发出信号
currentIndexChanged( const QString &txt)
2. QComboBoxItem 主题
代码显示:
ui->comboBoxFruit->addItem("apple");
ui->comboBoxFruit->addItem("orange");
connect(ui->pushButtonAdd,SIGNAL(clicked()) ,this, SLOT( btnAddClickedSlotFun() ));
connect(ui->pushButtonDel,SIGNAL(clicked()) ,this, SLOT( btnDelClickedSlotFun() ));
// 组合框的 信号: 当用户重新选择 item的时候,发出信号
connect(ui->comboBoxFruit,SIGNAL(currentIndexChanged( const QString &)),\
this, SLOT( comboxBoxFruitCurrentIndexChangedSlotFun( const QString &) ));
}
Widget::~Widget()
{
delete ui;
}
void Widget::btnAddClickedSlotFun()
{
QString str = ui->lineEditFruit->text();
//遍历防止冲突
for( int i=0; i<=ui->comboBoxFruit->count(); i++){
QString fruit = ui->comboBoxFruit->itemText(i);
if( str == fruit){
qDebug()<<"invalid, conflict"<<endl;
return ;
}
}
ui->comboBoxFruit->addItem( str );
}
void Widget::btnDelClickedSlotFun()
{
int curIndex = ui->comboBoxFruit->currentIndex(); //获取当前字符串的位置
ui->comboBoxFruit->removeItem( curIndex);
}
void Widget::comboxBoxFruitCurrentIndexChangedSlotFun(const QString &itemText)
{
qDebug()<<"find usr changed item:"<<itemText<<" "<<ui->comboBoxFruit->currentText()<<endl; //可以直接获取改变的item
ui->lineEditFruit->setText(itemText);
}
效果显示:
6.列表小控件 QListWidget
构成:
1.QListWidget 整体
添加Item addItem( QListWidget *item)
删除Item QListWidgetItem *takeItem( int row); // row删除第几个
注意:删除后,ListWidget 内部并没有释放该item的空间,只是返回该item的地址
让你自己去释放 空间 delete p;
更改查看模式: 图标模式 列表模式
setViewMode ( QListWidget:: IconMode/ QListWidget::ListModde )
获取当前用户选中的 item: int currentRow();
信号:
单击某个item QListWidget 发出信号 itemClicked( QListWidgetItem *item)
双击某个item itemDoubleClicked( QListWidgetItem *item)
2.QListWidgetItem :内部的小主题 (成员)
文本: 设置 setText(); 获取 QString text()
图标: 设置 setIcon( QIcon &icon) 设置大小: setSizeHint( &sz);
QSize sz(int w, int h); int sz.width() int sz.heigh()
代码显示:
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 创建 item mail phone
pMailItem = new QListWidgetItem;
QIcon icon(":/rs/Mail 512x512.ico"); //定义一个图标对象,使用后面的图标进行初始化
pMailItem->setIcon( icon ); //设置图标
pMailItem->setText("邮件");
phoneItem = new QListWidgetItem;
QIcon icon1(":/rs/iPhone 512x512.ico");
phoneItem->setIcon( icon1 );
phoneItem->setText("手机");
// 在 ListWidget 添加这两个item
ui->listWidget->addItem(pMailItem);
ui->listWidget->addItem(phoneItem);
//按钮动态增加
ui->lineEditName->setPlaceholderText("请输入item名字...");
connect(ui->btnAdd,SIGNAL(clicked() ),this, SLOT( btnAddClickedSlotFun() ));
//模式切换按钮
connect(ui->btnmode, SIGNAL(clicked()), this, SLOT( btnmodeClickedSLotFun() ));
//删除按钮
connect(ui->btnDelect, SIGNAL(clicked() ), this, SLOT( btnDelectClickedSlotFun() ));
//QListWidget 发出的信号处理
connect(ui->listWidget, SIGNAL(itemClicked(QListWidgetItem *)) , this, \
SLOT( listWidgetItemClickedSlotFun( QListWidgetItem *) ) );
connect(ui->listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem *)) , this, \
SLOT( listWidgetItemDoubleClickedSlotFun( QListWidgetItem *) ) );
}
Widget::~Widget()
{
delete ui;
}
void Widget::btnAddClickedSlotFun()
{
QString name = ui->lineEditName->text();
QString path = ":/rs/Calculator 512x512.ico"; //默认路径
if(name == "clock"){
path=":/rs/Clock 512x512.ico";
} else if(name =="Maps"){
path=":/rs/Maps 512x512.ico";
} else if(name =="Notes"){
path =":/rs/Notes 512x512.ico";
}
QListWidgetItem *p = new QListWidgetItem;
QIcon icon(path);
p->setIcon(icon);
p->setText(name);
ui->listWidget->addItem(p);
}
void Widget::btnmodeClickedSLotFun()
{
static int cnt =0;
cnt++;
if(cnt%2==1){
ui->listWidget->setViewMode( QListWidget::IconMode );
} else {
ui->listWidget->setViewMode( QListWidget::ListMode );
}
}
void Widget::btnDelectClickedSlotFun()
{
int pos = ui->listWidget->currentRow(); //获取当前用户选中的是第几个
QListWidgetItem *p = ui->listWidget->takeItem(pos);
delete p; //自己的空间,自己清理
}
void Widget::listWidgetItemClickedSlotFun(QListWidgetItem *it)
{
qDebug()<<"U clicked"<<it->text();
}
void Widget::listWidgetItemDoubleClickedSlotFun(QListWidgetItem *it)
{
qDebug()<<"U double clicked"<<it->text();
}
效果展示:
7.微调框 QSpinBox / QDoubleSpinBox ---double 类型
QSpinBox/QDoubleSpinBox:
类型 : T (int /double)
程序获取用户输入 T .value();
程序设置默认值 .setValue( T val);
设置最大值/最小值 :setMaximum( T val); setMinimum(int val)
设置后缀 : setSuffix(); 前缀: setPrefix
信号: 当内容发生改变的时候,发出一个信号
valueChanged( T val );
代码展示:
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
ui->spinBoxNum->setValue(4);
ui->spinBoxNum->setMaximum(1000);
ui->spinBoxNum->setMinimum(25);
ui->spinBoxNum->setSuffix(" KG");//后缀
ui->spinBoxNum->setPrefix("# "); //前缀
connect(ui->spinBoxNum,SIGNAL( valueChanged(int)),this,SLOT( spinBoxNumValueChangedSlotFun(int) ))
ui->doubleSpinBoxPrice->setValue(5.6);
ui->doubleSpinBoxPrice->setMaximum(56.3);
ui->doubleSpinBoxPrice->setMinimum(2.3);
ui->doubleSpinBoxPrice->setPrefix("羊 ");
ui->doubleSpinBoxPrice->setSuffix(" 元");
connect(ui->doubleSpinBoxPrice,SIGNAL(valueChanged(double)),this,SLOT(doubleSpinBoxValueChangedSlotFun(double) ));
}
Widget::~Widget()
{
delete ui;
}
void Widget::spinBoxNumValueChangedSlotFun(int val)
{
qDebug()<<"spinbox value="<<val<<" "<<ui->spinBoxNum->value();
double total = val * ui->doubleSpinBoxPrice->value();
//snprintf(buf,sizeof(buf),"total:%lf 元",total);
QString newstr = QString("%1 %2 %3").arg("羊 ").arg(total).arg(" 元");
ui->lineEdit->setText( newstr );
}
void Widget::doubleSpinBoxValueChangedSlotFun(double val)
{
qDebug()<<"double spinbox value="<<val <<" "<<ui->doubleSpinBoxPrice->value();
double total = val*ui->spinBoxNum->value();
QString newstr =QString("%1 %2 %3").arg("羊 ").arg(total).arg(" 元");
ui->lineEdit->setText(newstr);
}
8.滑动条 进度条
滑动条: 水平/垂直 Horizontal Slide / Vertical Slider
QSlider ---滑动输入
信号: valueChanged(int ) 当你拖动的时候,发出信号,包含当前值
设置:
最大值 setMaximum 最小值 setMinimum
默认值 : setValue(int) 获取当前值.int value
进度条: QSprogressBar 进度显示,用户不可改动
setValue(int val)
int value();
设置方向的 :setOrientation (QT::Vertical / QT::Horizontal) //使用QT宏定义
设置大小: reSize(x,y);
总结
QT的控件很多很杂,遇到了要灵活运用。学习控件主要从两个两个方面学习,一是显示,二就是信号。