学习自黑马程序员&传智教育
添加资源文件,图片视频等:
添加新文件 -》Qt -》 Qt资源文件 -》设定名称如:res
最后在项目栏出现 资源文件,资源下出现 res.qrc文件,右键 Open in Editor -》添加 -》添加前缀 如:/ -》然后就可以添加文件
.pro文件,类似VS项目的.sln文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = myWiget TEMPLATE = app SOURCES += main.cpp\ mywidget.cpp HEADERS += mywidget.h FORMS += mywidget.ui
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include "mywidget.h" #include <QApplication> int main (int argc, char *argv[]) { QApplication a (argc, argv) ; myWidget w; return a.exec (); }
QT使用Lambda,在.pro
文件中追加 CONFIG += c++11
1 2 3 4 5 6 7 8 9 QPushButton *mbtn1 = new QPushButton (this ); QPushButton *mbtn2 = new QPushButton (this ); mbtn1->move (100 , 0 ); mbtn2->move (100 , 50 ); int m = 10 ;connect (mbtn1, &QPushButton::clicked, this , [m]()mutable { m = 100 + 10 ; qDebug () << m; });connect (mbtn2, &QPushButton::clicked, this , [=](){ qDebug () << m; });
按钮QPushButton
继承关系:QWidget <- QAbstractButton <- QPushButton
1 2 3 4 5 6 7 8 9 10 11 12 13 14 QPushButton *btn = new QPushButton (); btn->setParent (this ); btn->setText ("第一个按钮" ); QPushButton *btn2 = new QPushButton ("第二个按钮" , this ); btn2->move (100 , 100 ); btn2->resize (50 , 50 );
对象树
构造重上向下,析构重下向上,一定程度上简化了内存的回收机制,前提要制定父亲setParent()
信号和槽 信号signal
和槽slot
1 2 3 connect (myBtn, &QPushButton::clicked, this , &myWidget::close);
自定义信号和槽
自定义信号:写到 signals
下
返回 void
需要声明,不需要实现
可以有参数,可以重载
自定义槽函数:写到public slot
下或 public
或者全局函数
需要声明和实现
可以有参数,可以重载
返回 void
1 2 3 4 5 6 7 8 class Teacher : public QObject{ ... signals: void hungry () ; ... }
1 2 3 4 5 6 7 8 9 10 11 class Student : public QObject{ ... public slots: void treat () ; ... }
1 2 3 4 5 6 7 ... void Student::treat () { qDebug () << "请老师吃饭" ; } ...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ... this ->zt = new Teacher (this );this ->st = new Student (this );connect (zt, &Teacher::hungry, st, &Student::treat);classIsOver ();... void myWidget::classIsOver () { emit zt->hungry (); }
自定义信号和槽出现重载时
利用函数指针明确函数地址 void(Teacher::*tSignal)(QString) = &Teacher::hungry()
QString
转 char*
:先转成 QByteArray
.toUtf8()
在转 char*
.data()
1 2 3 4 5 6 7 8 9 10 11 12 13 void hungry (QString foodName) ;void treat (QString foodName) { qDebug () << "请老师吃:" << foodName.toUtf8 ().data (); } void (Teacher:: *teacherSignal)(QString) = &Teacher::hungry;void (Student:: *studentSlot)(QString) = &Student::treat;connect (zt, teacherSignal, st, studentSlot);classIsOver ();
信号可以连接信号
1 2 3 4 void (Teacher:: *teacherSignal2)() = &Teacher::hungry;void (Student:: *studentSlot2)() = &Student::treat;connect (zt, teacherSignal2, st, studentSlot2); connect (btn, &QPushButton::clicked, zt, teacherSignal2);
信号可以断开disconnect
1 disconnect (btn, &QPushButton::clicked, zt, teacherSignal2);
拓展
1、信号是可以连接信号
2、一个信号可以连接多个槽函数
3、多个信号 可以连接 同一个槽函数
4、信号和槽函数的参数必须一一对应
5、信号的参数个数 可以多于 槽函数的参数,但前面的类型还是要对应
6、QT4版本的信号连接 connect(zt, SIGNAL(hungry()), st, SLOT(treat()));
窗口控件 菜单栏,工具栏,状态栏,铆接部件,核心部件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 QMenuBar *bar = menuBar (); setMenuBar (bar); QMenu *fileMenu = bar->addMenu ("文件" ); QMenu *editMenu = bar->addMenu ("编辑" ); QAction *newAction = fileMenu->addAction ("新建" ); fileMenu->addSeparator (); QAction *openAction = fileMenu->addAction ("打开" ); QToolBar *toolBar = new QToolBar (this ); addToolBar (Qt::LeftToolBarArea, toolBar); toolBar->setMovable (false ); toolBar->setAllowedAreas (Qt::LeftToolBarArea | Qt::RightToolBarArea); toolBar->setFloatable (false ); toolBar->addAction (newAction); toolBar->addSeparator (); toolBar->addAction (openAction); QPushButton *btn = new QPushButton ("aa" , this ); toolBar->addWidget (btn); QStatusBar *stBar = statusBar (); setStatusBar (stBar); QLabel * label = new QLabel ("提示信息" , this ); stBar->addWidget (label); QLabel * label2 = new QLabel ("最右边" , this ); stBar->addPermanentWidget (label2); QDockWidget *dockWidget = new QDockWidget ("浮动" , this ); addDockWidget (Qt::BottomDockWidgetArea, dockWidget); dockWidget->setAllowedAreas (Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea); QTextEdit *textEdit = new QTextEdit (this ); setCentralWidget (textEdit);
按钮
QPushButton:常用按钮
QToolButton:工具按钮 ,用于显示图片
显示文字,修改 toolButtonStytle
凸起风格 autoRaise
RadioButton:单选按钮 ,设置默认 ui->按钮名称->setChecked(true);
CheckBox:多选按钮 ,监听状态,2选择,0未选
1 2 3 4 5 6 7 8 9 10 11 12 ui->rBtnMan->setChecked (true ); connect (ui->rBtnWoman, &QRadioButton::clicked, [=](){ qDebug () << "选中性别女" <<endl; }); connect (ui->cBox, &QCheckBox::stateChanged, [=](int state) { qDebug () << state; });
QListWidget:列表容器
1 2 3 4 5 6 7 8 9 10 11 QStringList list; list << "锄禾日当午" << "汗滴禾下土" << "谁知盘中餐" << "粒粒皆辛苦" ; ui->listWidget->addItems (list);
QTreeWidget:树控件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ui->treeWidget->setHeaderLabels (QStringList () << "英雄" << "英雄介绍" ); QTreeWidgetItem * liItem = new QTreeWidgetItem (QStringList () << "力量" ); QTreeWidgetItem * miItem = new QTreeWidgetItem (QStringList () << "敏捷" ); ui->treeWidget->addTopLevelItem (liItem); ui->treeWidget->addTopLevelItem (miItem); QStringList heroL1, heroL2; heroL1 << "赵云" << "天美亲儿子" ; heroL2 << "李白" << "打野一哥" ; QTreeWidgetItem *l1 = new QTreeWidgetItem (heroL1); QTreeWidgetItem *l2 = new QTreeWidgetItem (heroL2); liItem->addChild (l1); liItem->addChild (l2);
QTableWidget:表格控件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ui->tableWidget->setColumnCount (3 ); ui->tableWidget->setHorizontalHeaderLabels (QStringList () << "姓名" << "性别" << "年龄" ); ui->tableWidget->setRowCount (5 ); QStringList nameList; nameList << "亚瑟" << "赵云" << "张飞" << "关羽" << "花木兰" ; QList<QString> sexList; sexList << "男" << "男" << "男" << "男" << "女" ; for (int i = 0 ; i < 5 ; ++i) { int col = 0 ; ui->tableWidget->setItem (i, col++, new QTableWidgetItem (nameList[i])); ui->tableWidget->setItem (i, col++, new QTableWidgetItem (sexList[i])); ui->tableWidget->setItem (i, col++, new QTableWidgetItem (QString::number (i+18 ))); }
其他控件
Stacked Widget
栈控件 ui->stackedWidget->setCurrentIndex(1);
combo Box
下拉框 ui->comboBox->addItem("奔驰");
QLable
标签
显示图片 ui->label_pic->setPixmap(QPixmap(":/Image/butterfly.png"));
显示动图 QMovie movie = new QMovie("路径"); ui->lable_movie->setMovie(movie); movie->start();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 ui->stackedWidget->setCurrentIndex (2 ); connect (ui->btn_ScrollArea, &QPushButton::clicked, [=](){ ui->stackedWidget->setCurrentIndex (2 ); }); connect (ui->btn_ToolBox, &QPushButton::clicked, [=](){ ui->stackedWidget->setCurrentIndex (1 ); }); connect (ui->btn_TabWidget, &QPushButton::clicked, [=](){ ui->stackedWidget->setCurrentIndex (0 ); }); ui->comboBox->addItem ("奔驰" ); ui->comboBox->addItem ("宝马" ); ui->comboBox->addItem ("拖拉机" ); connect (ui->btn_Select, &QPushButton::clicked, [=](){ ui->comboBox->setCurrentText ("拖拉机" ); }); ui->label_Pic->setPixmap (QPixmap ("E:/QT/HeiMa_jiaocheng/06_QtControl/Image/butterfly.png" )); QMovie * movie = new QMovie ("E:/QT/HeiMa_jiaocheng/06_QtControl/Image/mario.gif" ); ui->label_movie->setMovie (movie); movie->start ();
对话框 模态对话框、非模态对话框
1 2 3 4 5 6 7 8 9 10 11 QDialog dlg (this ) ;dlg.resize (200 , 100 ); dlg.exec (); QDialog *dlg2 = new QDialog (this ); dlg2->resize (200 , 100 ); dlg2->show (); dlg2->setAttribute (Qt::WA_DeleteOnClose);
消息对话框: 模态,QMessageBox
错误对话框 QMessageBox::critical
信息对话框 QMessageBox::information
问题对话框 QMessageBox::question
警告对话框 QMessageBox::warning
1 2 3 4 5 6 7 8 9 10 11 12 QMessageBox::critical (this , "critical" , "错误" ); QMessageBox::information (this , "info" , "信息" ); if (QMessageBox::Save == QMessageBox::question (this , "ques" , "提问" , QMessageBox::Save | QMessageBox::Cancel, QMessageBox::Cancel)) { qDebug () << "已保存" ; } QMessageBox::warning (this , "Warning" , "警告" );
颜色对话框: QColorDialog
1 2 3 QColor color = QColorDialog::getColor (QColor (255 , 0 , 0 )); qDebug () << "r = " << color.red () << " g = " << color.green () << " b = " << color.blue () << endl;
文件对话框 :QFileDialog
1 2 3 4 QString str = QFileDialog::getOpenFileName (this , "打开文件" , "D:\\MLZ107\\Desktop" , "(*.txt)" ); qDebug () << str << endl;
字体对话框 :QFontDialog
1 2 3 4 bool flag;QFont font = QFontDialog::getFont (&flag, QFont ("仿宋" , 14 )); qDebug () << "字体:" << font.family () << " 字号:" << font.pointSize () << " 是否加粗:" << font.bold () << " 是否倾斜:" << font.italic ();
窗口布局
Push Button:按钮
Label:标签
Line Edit:单行输入
Horizontal Spacer:水平弹簧
Vertical Spacer:垂直弹簧
Vertical Layout:垂直布局
Horizontal Layout:水平布局
Grid Layout:栅格布局
默认窗口和控件之间有间隙,可以调整
自定义控件封装 添加新文件 -》Qt -》设计师界面类 要设置要继承的类如widget,会生成 (.h .cpp . ui)
.ui文件中该控件的功能,并在.h,.cpp文件中提供接口
主界面的.ui文件中添加widget控件,右键提升为自定义的控件
事件 鼠标事件QMouseEvent
鼠标进入 enterEvent
鼠标离开事件 leaveEvent
鼠标按下 mousePressEvent
鼠标释放 mouseReleaseEvent
鼠标移动 mouseMoveEvent
ev->x()
鼠标x的坐标 ev->y()
鼠标y的坐标
ev->button()
判断按键 Qt::LeftButton
Qt::RightButton
ev->buttons()
判断组号按键 判断移动时 Qt::LeftButton & Qt::RightButton
格式化字符串 QString("%1 %2").arg(111).arg("我的");
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 ... void myLabel::enterEvent (QEvent *ev) { qDebug () << "鼠标进入myLabel" ; } void myLabel::leaveEvent (QEvent *ev) { qDebug () << "鼠标离开myLabel" ; } void myLabel::mousePressEvent (QMouseEvent *ev) { if (ev->button () == Qt::LeftButton) { qDebug () << "鼠标按下:x = " << ev->x () << " y = " << ev->y () << " globalX = " << ev->globalX () << " globalY = " << ev->globalY (); } } void myLabel::mouseMoveEvent (QMouseEvent *ev) { if (ev->buttons () & Qt::LeftButton) { qDebug () << "鼠标移动:x = " << ev->x () << " y = " << ev->y () << " globalX = " << ev->globalX () << " globalY = " << ev->globalY (); } } void myLabel::mouseReleaseEvent (QMouseEvent *ev) { if (ev->button () == Qt::RightButton) { QString str = QString ("鼠标释放:x = %1 y = %2 globalX = %3 globalY = %4" ).arg (ev->x ()).arg (ev->y ()).arg (ev->globalX ()).arg (ev->globalY ()); qDebug () << str; } }
定时器事件
重写事件 void timerEvent(QTimerEvent *);
启动定时器 startTimer(1000);
单位:ms
,返回值 :int
定时器的唯一标识id
startTimer
返回值 可以和 ev->timeId()
比较,选择执行哪个定时事件
关闭定时器killTimer(int id);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 id1 = startTimer (1000 ); id2 = startTimer (2000 ); void Widget::timerEvent (QTimerEvent *ev) { if (id1 == ev->timerId ()) { static int num1 = 1 ; ui->label_2->setText (QString::number (num1++)); } if (id2 == ev->timerId ()) { static int num2 = 1 ; ui->label_3->setText (QString::number (num2++)); } }
定时器类QTimer :创建定时事件的第二种用法,推荐,定时事件分开,比较独立
创建定时器对象 QTimer * timer = new QTimer(this);
启动定时器 timer->start(1000);
单位:ms
每隔一定时间,发送信号 timeout
,监听 connect(timer, &Timer::timeout, 目标函数);
,目标函数为每个一定时间想做的事
暂停 timer->stop();
isActive()
判断定时器是否已启动,避免重复启动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 QTimer *timer = new QTimer (this ); timer->start (500 ); connect (timer, &QTimer::timeout, [=](){ static int num = 1 ; ui->label_4->setText (QString::number (num++)); }); static bool flag = true ;connect (ui->btn, &QPushButton::clicked, [=](){ if (flag) { timer->stop (); ui->btn->setText ("恢复" ); } else { timer->start (500 ); ui->btn->setText ("暂停" ); } flag = !flag; });
事件分发器 :用于事件的分发,可以做拦截操作,不建议
type()
用于判断时间的类型,如:MouseButtonPress、MouseButtonMove
1 2 3 4 5 6 7 8 9 10 11 12 13 14 bool myLabel::event (QEvent *e) { if (QEvent::MouseButtonPress == e->type ()) { QMouseEvent *ev = static_cast <QMouseEvent*>(e); QString str = QString ("Event函数中:鼠标按下 x = %1 y = %2 globalX = %3 globalY = %4" ).arg (ev->x ()).arg (ev->y ()).arg (ev->globalX ()).arg (ev->globalY ()); qDebug () << str; return true ; } return QLabel::event (e); }
事件过滤器 :在程序将事件分发到事件分发器前,可以利用过滤器做拦截
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ... bool eventFilter (QObject *, QEvent *) ; ... ... bool Widget::eventFilter (QObject *obj, QEvent *e) { if (obj == ui->label) { if (e->type () == QEvent::MouseButtonPress) { QMouseEvent *ev = static_cast <QMouseEvent*>(e); QString str = QString ("事件过滤器中:鼠标按下 x = %1 y = %2 globalX = %3 globalY = %4" ).arg (ev->x ()).arg (ev->y ()).arg (ev->globalX ()).arg (ev->globalY ()); qDebug () << str; return true ; } } return QWidget::eventFilter (obj, e); }
绘图QPainter
绘图事件 void paintEvent(QPaintEvent *);
自动调用
声明一个画家对象 QPainter painter(this);
this指定绘图设备
设置画笔 QPen
设置画笔宽度 setWidth
风格 setStyle
设置画刷 QBrush
风格setStyle
画家使用画笔painter.setPen(pen);
使用画刷 painter.setBrush(brush);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 void Widget::paintEvent (QPaintEvent *) { QPainter painter (this ) ; QPen pen (QColor(255 , 0 , 0 )) ; pen.setWidth (3 ); pen.setStyle (Qt::DotLine); QBrush brush (Qt::cyan) ; brush.setStyle (Qt::Dense7Pattern); painter.setBrush (brush); painter.setPen (pen); painter.drawLine (QPoint (0 , 0 ), QPoint (100 , 100 )); painter.drawEllipse (QPoint (100 , 100 ), 50 , 50 ); painter.drawRect (QRect (20 , 20 , 50 , 50 )); painter.drawText (QRect (10 , 200 , 150 , 50 ), "好好学习,天天向上" ); }
抗锯齿 效率低 painter.setRenderHint(QPainter::Antialiasing);
画家移动位置 QPainter.translate(100, 0);
保存状态 save();
还原状态 restore();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 void Widget::paintEvent (QPaintEvent *) { QPainter painter (this ) ; painter.setRenderHint (QPainter::Antialiasing); painter.drawEllipse (QPoint (50 , 50 ), 50 , 50 ); painter.translate (100 , 0 ); painter.drawRect (20 , 20 , 50 , 50 ); painter.translate (100 , 0 ); painter.drawRect (20 , 20 , 50 , 50 ); painter.save (); painter.translate (0 , 100 ); painter.restore (); painter.drawEllipse (QPoint (30 , 30 ), 10 , 10 ); }
利用画家画图片
将图片添加到项目资源中
painter.drawPixmap(x, y, QPixmap(":/Image/Luffy.png"));
(x,y)绘图起点坐标
手动调用绘图事件进行更新,推荐update()
,当然repaint()
也可以
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 connect (ui->btn, &QPushButton::clicked, [=](){ posX += 20 ; update (); }); QTimer *timer = new QTimer (this ); timer->start (500 ); connect (timer, &QTimer::timeout, [=](){ posX += 10 ; update (); }); ... void Widget::paintEvent (QPaintEvent *) { QPainter painter (this ) ; if (posX > this ->width ()) { posX = -QPixmap (":/Image/Luffy.png" ).width (); } painter.drawPixmap (posX, 0 , QPixmap (":/Image/Luffy.png" )); }
绘图设备 QPaintDevice 的子类在Qt里面有4中:
前例中在QWidget
能画图是因为QWidget
继承自QPaintDevice
QPixmap
创建QPixmap pix(w, h);
填充颜色 pix.fill(颜色);
利用画家在pix上画画 QPainter painter(&pix);
保存 pix.save(路径);
1 2 3 4 5 6 7 8 9 10 11 12 QPixmap pix (300 , 300 ) ; pix.fill (Qt::white); QPainter painter (&pix) ; painter.setPen (QPen (Qt::green)); painter.drawEllipse (QPoint (150 , 150 ), 100 , 100 ); pix.save ("E:/QT/pix.png" );
QImage
创建 QImage img(w, h, QImage::Format_RGB32);
设置像素 setPixel(x, y, value);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 QImage img (300 , 300 , QImage::Format_ARGB32) ; img.fill (Qt::white); QPainter painter (&img) ; painter.setPen (QPen (Qt::blue)); painter.drawEllipse (QPoint (150 , 150 ),100 ,100 ); img.save ("E:/QT/img.png" ); ... void Widget::paintEvent (QPaintEvent *) { QPainter painter (this ) ; QImage img; img.load (":/Image/Luffy.png" ); for (int i = 50 ; i < 100 ; ++i) { for (int j = 50 ; j < 100 ; ++j) { QRgb value = qRgb (255 ,0 ,0 ); img.setPixel (i, j, value); } } painter.drawImage (0 , 0 , img); }
QPicture :可以记录和重现绘图指令,但不能直接显示图片
创建 QPicture pic
开始记录 painter.begin(&pic);
结束记录 painter.end();
保存 pic.save("路径任意后缀名");
重现 利用画家重现 painter.drawPicture(x, y, pic);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 QPicture pic; QPainter painter; painter.begin (&pic); painter.setPen (QPen (Qt::blue)); painter.drawEllipse (QPoint (150 , 150 ), 100 , 100 ); painter.end (); pic.save ("E:/QT/pic.pic" ); ... void Widget::paintEvent (QPaintEvent *) { QPainter painter (this ) ; QPicture pic; pic.load ("E:/QT/pic.pic" ); painter.drawPicture (0 , 0 , pic); }
QBitmap
1 2 3 4 5 6 7 8 9 10 11 12 13 void PaintWidget::paintEvent (QPaintEvent *) { QPixmap pixmap (":/Image/butterfly.png" ) ; QPixmap pixmap1 (":/Image/butterfly1.png" ) ; QBitmap bitmap (":/Image/butterfly.png" ) ; QBitmap bitmap1 (":/Image/butterfly1.png" ) ; QPainter painter (this ) ; painter.drawPixmap (0 , 0 , pixmap); painter.drawPixmap (200 , 0 , pixmap1); painter.drawPixmap (0 , 130 , bitmap); painter.drawPixmap (200 , 130 , bitmap1); }
文件读取 QFile文件读取
QFileDialog文件对话框
QByteArray
QFileInfo文件信息类
QTextCodec编码格式类
QFile默认支持的格式为UTF-8
1 2 3 4 5 6 7 8 QFile file (path) ; file.open (QIODevice::ReadOnly); QByteArray array = file.readAll (); QByteArray array2; while (!file.atEnd ()) { array2 += file.readLine (); }
编码格式类QTextCodec
1 2 QTextCodec * codec = QTextCodec::codeForName ("gbk" ); codec->toUnicode (array);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 connect (ui->pushButton, &QPushButton::clicked, [=](){ QString str = QFileDialog::getOpenFileName (this , "打开文件" , "D:\\MLZ107\\Desktop" ); ui->lineEdit->setText (str); QTextCodec *codec = QTextCodec::codecForName ("GBK" ); QFile file (str); file.open (QIODevice::ReadOnly); QByteArray array = file.readAll (); ui->textEdit->setText (codec->toUnicode (array)); file.close (); });
1 2 3 4 5 file.open (str); file.open (QIODevice::Append); file.write ("fjeofj都无可哦" ); file.close ();
QFileInfo 读取文件信息
1 2 3 4 5 6 info.size (); info.suffix (); info.fileName (); info.filePath (); info.created ().toString ("yyyy/MM/dd hh:mm:ss" ); info.lastModified ()toString ("yyyy/MM/dd hh:mm:ss" );
1 2 3 4 QFileInfo info (str) ;qDebug () << "文件大小:" << info.size () << " 后缀名:" << info.suffix () << " 文件名:" << info.fileName () << " 文件路径:" << info.filePath ();qDebug () << "创建日期:" << info.created ().toString ("yyyy/MM/dd hh:mm:ss" );qDebug () << "最后修改时间:" << info.lastModified ().toString ("yyyy/MM/dd hh:mm:ss" );
项目打包 1、使用QT
的Release构建项目,将构建出来的exe
文件单独放置一个空文件夹中
2、确保QT
的安装路径D:\Qt\Qt5.3.1\5.3\mingw482_32\bin
有windeployqt.exe
文件添加在环境变量中
3、在exe
所在空文件中打开cmd
窗口输入 windeployqt xxx.exe
第三方软件打包:hm nis edit
Socket通信 Qt中提供的所有的Socket类都是非阻塞的。
Qt中常用的用于socket通信的套接字类:
QTcpServer:用于TCP/IP通信, 作为服务器端套接字使用
QTcpSocket:用于TCP/IP通信,作为客户端套接字使用
QUdpSocket:用于UDP通信,服务器,客户端均使用此套接字
要在.pro
文件中添加 network
模块
TCP/IP UDP 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 #include "widget.h" #include "ui_widget.h" #include <QHostAddress> Widget::Widget (QWidget *parent) : QWidget (parent), ui (new Ui::Widget) { ui->setupUi (this ); udpSocket = new QUdpSocket (this ); udpSocket->bind (8880 ); setWindowTitle ("端口号:8880" ); connect (udpSocket, &QUdpSocket::readyRead, this , &Widget::dealMsg); } Widget::~Widget () { delete ui; } void Widget::dealMsg () { char buf[1024 ] = {0 }; QHostAddress peerIP; quint16 peerPort; qint64 len = udpSocket->readDatagram (buf, sizeof (buf), &peerIP, &peerPort); if (len > 0 ) { QString str = QString ("[%1:%2] %3" ).arg (peerIP.toString ()).arg (peerPort).arg (buf); ui->textEdit->setText (str); } } void Widget::on_ButtonSend_clicked () { QString ip = ui->lineEditIP->text (); quint16 port = ui->lineEditPort->text ().toInt (); QString str = ui->textEdit->toPlainText (); udpSocket->writeDatagram (str.toUtf8 (), QHostAddress (ip), port); }
组播地址:
1 2 3 4 5 6 udpSocket->bind (QHostAddress::AnyIPv4, 8888 ); udpSocket->joinMulticastGroup (QHostAddress ("224.0.0.2" )); udpSocket->leaveMulticastGroup ();