下载和安装
安装时如果操作系统为 Windows,则应该安装 MinGW 版本
Qt Creator
QWidget
类:不带菜单栏的
QMainWindow
类:带菜单栏的
界面:代码实现和图形界面分开
代码区有头文件和相应的实现(都在类中)
图形界面有插件和相应的属性设置
有不知道的命令可以在左侧帮助
中查
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); }
|
信号与槽
插入信号和槽的方法
最直接的:右键对象,转到槽
,只需直接在所给的函数中写代码
向 private slots
中添加函数声明,并连接信号与槽:
谁发出信号,发出什么信号,谁处理信号,怎么处理信号
例如:connnect(ui->cmdLineEdit, SIGNAL(returnPressed()), this, SLOT(on_commitButton_clicked()));
也可以:connect(ui->cancelButton, &QPushButton::clicked, this, &Widget::on_cancelButton_clicked);
后面部分可以写成 lambda 表达式:
connect(ui->browseButton, &QPushButton::clicked, [this](){ QMessageBox::information(this, "信息", "点击浏览"); });
|
自定义信号
头文件里写:
signals: void sendToWidget();
|
发出信号:emit sendToWidget()
信号可以包含参数,槽也可以包含参数,且允许传递无用的信号
- 一个信号可以连接多个槽,但这些槽执行顺序不确定
- 一个槽可以与多个信号相连,只要接收到其中一个信号,就会执行该槽
实现计算器
this->setWindowTitle("计算器");this->setFixedSize(200, 280);
this->setWindowTitle("计算器");
QFont f("仿宋", 14); ui->mainLineEdit->setFont(f);
QIcon icon("E:\\code\\Qt\\calculator\\tt.jpg"); ui->deleteButton->setIcon(icon);
ui->equalButton->setStyleSheet("background:blue");
|
计时器
QObject
使用放在基类 QObject
中的计时器
定义函数:virtual void timerEvent(QTimerEvent *event)
开始计时:myTimerId = this->startTimer(TIMEOUT)
void Widget::timerEvent(QTimerEvent *event) { if (event->timerId() != myTimerId) return;
QString path("E:\\Pictures\\正经的\\琉璃神社壁纸包 2022年6月号\\"); path += QString::number(picId) + ".jpg";
QImage img(path); ui->label->setPixmap(QPixmap::fromImage(img));
picId++; if (picId > 42) picId = 10; }
|
QTimer
定义:QTimer* timer
连接信号与槽:connect(timer, &QTimer::timeout, this, &Widget::timeoutSlot)
时间到了执行一次:QTimer::singleShot(TIMEOUT, this, SLOT(timeoutSlot()));
文件操作
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this);
connect(ui->newAction, &QAction::triggered, this, &MainWindow::newActionSlot); connect(ui->openAction, &QAction::triggered, this, &MainWindow::openActionSlot); connect(ui->saveAction, &QAction::triggered, this, &MainWindow::saveActionSlot); }
MainWindow::~MainWindow() { delete ui; }
void MainWindow::newActionSlot() { ui->textEdit->clear(); this->setWindowTitle("新建文本文档.txt"); }
void MainWindow::openActionSlot() { QString fileName = QFileDialog::getOpenFileName(this, "选择一个文件", QCoreApplication::applicationFilePath(), "*.cpp"); if (fileName.isEmpty()) QMessageBox::warning(this, "警告", "请选择一个文件"); else { QFile file(fileName); file.open(QIODevice::ReadOnly); ui->textEdit->setText(QString(file.readAll())); file.close(); } }
void MainWindow::saveActionSlot() { QString fileName = QFileDialog::getSaveFileName(this, "请选择一个文件", CoreApplication::applicationFilePath()); if (fileName.isEmpty()) QMessageBox::warning(this, "警告", "请选择一个文件"); else { QFile file(fileName); file.open(QIODevice::WriteOnly); file.write(ui->textEdit->toPlainText().toLocal8Bit()); file.close(); } }
|
文件的打开与文件信息的获取
int main(int argc, char *argv[]) { QApplication app(argc, argv);
QFile file("in.txt"); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qDebug() << "Open file failed."; return -1; } else { while (!file.atEnd()) { qDebug() << file.readLine(); } }
QFileInfo info(file); qDebug() << info.isDir();
return app.exec(); }
|
QFileInfo
的一些函数:
函数名 |
用处 |
isDir() |
检查该文件是否是目录 |
isExecutable() |
检查该文件是否是可执行文件 |
baseName() |
获取文件名( |
completeBaseName() |
获取完整的文件名 |
suffix() |
获取文件后缀名 |
completeSuffix() |
获取完整的文件后缀 |
二进制文件读写
使用 QDataStream
类
QFile file("file.dat"); file.open(QIODevice::WriteOnly); QDataStream out(&file); out << QString("the answer is"); out << (qint32)42; file.close();
QFile file("file.dat"); file.open(QIODevice::ReadOnly); QDataStream in(&file); QString str; qint32 a; in >> str >> a;
|
文本文件读写
使用 QTextStream
类
读写方法类似
鼠标和键盘事件
所需头文件:
#include <QKeyEvent>
#include <QMouseEvent>
void MainWindow::keyPressEvent(QKeyEvent *k) { if (k->modifiers() == Qt::ControlModifier && k->key() == Qt::Key_S) saveActionSlot(); }
void MainWindow::mousePressEvent(QMouseEvent *m) { QPoint pt = m->pos(); qDebug() << pt; if (m->button() == Qt::LeftButton) { qDebug() << "左键被按下"; } else if (m->button() == Qt::RightButton) { qDebug() << "右键被按下"; } }
|
启动新窗口
类似于 main.cpp
中所写的
因为 show
并不会阻塞函数,所以这个函数会继续执行,所以必须在堆空间而不是栈空间创建对象
Chat *c = new Chat(socket);
c->show();
|
多线程
新建一个继承自 QThread
的类 myThread
,该类中须实现线程处理函数 run()
调用:
myThread *t = new myThread; t->start();
|
绘图
坐标原点在左上角,向右为 x 轴正方向,向下为 y 轴正方向
需要 <QPainter>
头文件
事件为:void paintEvent(QPaintEvent *)
调用:
void PaintedWidget::paintEvent(QPaintEvent *) { QPainter painter(this); painter.drawLine(80, 100, 650, 500); painter.setPen(Qt::red); painter.drawRect(10, 10, 100, 400); painter.setPen(QPen(Qt::green, 5)); painter.setBrush(Qt::blue); painter.drawEllipse(50, 150, 400, 200); }
|
若想要再次手动调用该事件,使用 `update()