C++

Qt learn

"let us learn Qt deeply"

Posted by HZY on October 28, 2025
基本类型
IO
1
2
3
4
5
6
7
qDebug()<<"";
qDebug("%s %d","hello",1);
qInfo()<<
qWarning()<<
qCritical()<<

qFatal()//这个不能使用流输出
QByteArray
1
2
3
4
5
6
append(qbarr)
push_front(qbarr)
push_front(qbarr)
insert(int,qbarr)
remove(pos,len)
chop(int) //截断最后几个
QPushButton
1
2
3
4
5
6
7
QPushButton *btn = new QPushButton;
btn->setParent(this);
btn->setText("a");
btn->move(100,100);

QPushButton *btn = new QBushBotton("btn",this);

创建对象的时机

平安无事

{ QWidget window; QPushButton quit(“Quit”, &window); }

程序崩溃

{ QPushButton quit(“Quit”); QWidget window; quit.setParent(&window); }

信号与槽机制

基本认识
1
2
3
4
QPushButton * quitbtn = new QPushButton("关闭窗口",this);
connect(quitBtn,&QPushButton::clicked,this,&MyWidget::close);

connect(sender, signal, receiver, slot);

Signals

  • clicked(bool checked = false)
  • pressed()
  • released()
  • toggled(bool checked)
    自定义信号
  • 声明在类的signals域下
  • 没有返回值,void类型的函数
  • 只有函数声明,没有定义
  • 可以有参数,可以重载
  • 通过emit关键字来触发信号,形式:emit object->sig(参数); ``` cpp signals: void hungry();

void MyWidget::ClassIsOver(){

1
2
emit teacher->hungry(); } ``` ##### 自定义槽 * qt4 必须声明在 private/public/protected slots域下面,qt5之后可以声明public下,同时还可以是静态的成员函数,全局函数,lambda表达式 * 没有返回值,void类型的函数 * 不仅有声明,还得要有实现 * 可以有参数,可以重载 ``` cpp public slots:
   void treat();

void Student::treat(){ qDebug() « “Student treat teacher”; }

//lambda connect(btn,&QPushButton::clicked,={ qDebug()«“Clicked”; });

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
#### QMainWindow
>QMainWindow是一个为用户提供主窗口程序的类,包含一个菜单栏(menu bar)、多个工具栏(tool bars)、多个停靠部件(dock widgets)、一个状态栏(status bar)及一个中心部件(central widget),是许多应用程序的基础,如文本编辑器,图片编辑器等。
##### 菜单栏
``` cpp
QMenuBar *  menuBar() const; //调用函数自动创建

QAction* addMenu(QMenu * menu);
QMenu* addMenu(const QString & title);
QMenu* addMenu(const QIcon & icon, const QString & title);

QAction* activeAction() const;
QAction* addAction(const QString & text);
QAction* addAction(const QIcon & icon, const QString & text);
QAction* addAction(const QString & text, const QObject * receiver,
const char * member, const QKeySequence & shortcut = 0);
QAction* addAction(const QIcon & icon, const QString & text, 
const QObject * receiver, const char * member, 
const QKeySequence & shortcut = 0);

//示例
// 在 QMainWindow 子类中添加菜单栏、菜单和动作
void MainWindow::initMenu() {
    QMenuBar *bar = menuBar(); // 获取菜单栏
    QMenu *fileMenu = bar->addMenu("文件"); // 添加“文件”菜单
    QAction *newAct = fileMenu->addAction("新建", this, &MainWindow::newFile, QKeySequence::New); // 添加“新建”动作并绑定槽函数、快捷键
    QAction *openAct = fileMenu->addAction(QIcon("open.png"), "打开", this, &MainWindow::openFile); // 带图标的“打开”动作
}
工具栏
1
2
3
4
5
6
7
8
9
Qt::LeftToolBarArea           //停靠在左侧
Qt::RightToolBarArea         //停靠在右侧
Qt::TopToolBarArea           //停靠在顶部
Qt::BottomToolBarArea   //停靠在底部
Qt::AllToolBarAreas          // 以上四个位置都可停靠

setAllowedAreasQt::LeftToolBarArea | Qt::RightToolBarArea
setFloatabletrueOrFalse
setMoveabletrueOrFalse
状态栏

一个QMainWindow的程序最多只有一个状态栏。QMainWindow中可以有多个的部件都使用add…名字的函数,而只有一个的部件,就直接使用获取部件的函数,如menuBar。同理状态栏也提供了一个获取状态栏的函数statusBar(),没有就自动创建一个并返回状态栏的指针。

1
2
3
4
5
6
7
8
9
 QMenuBar *	menuBar() const;

void addWidget(QWidget * widget, int stretch = 0);
//插入小部件
int	insertWidget(int index, QWidget * widget, int stretch = 0);
//删除小部件
void removeWidget(QWidget * widget);

void addPermenentWidget (QWidget *widget, int stretch = 0);
停靠部件(也成为铆接部件、浮动窗口)
核心部件(中心部件)

跳过

QDialog 对话框

模态对话框

1.应用程序级别的模态 当该种模态的对话框出现时,用户必须首先对对话框进行交互,直到关闭对话框,然后才能访问程序中其他的窗口。 使用QDialog::exec()实现应用程序级别的模态对话框 2.窗口级别的模态 该模态仅仅阻塞与对话框关联的窗口,但是依然允许用户与程序中其它窗口交互。窗口级别的模态尤其适用于多窗口模式。 使用QDialog::open()实现窗口级别的模态对话框 一般情况下我们只使用应用程序级别的模态对话框。

1
2
3
4
5
6
7
8
9
 QDialog dialog;
    dialog.setWindowTitle(tr("Hello, dialog!"));

//避免内存泄漏
QDialog *dialog = new QDialog;
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setWindowTitle(tr("Hello, dialog!"));
dialog->show();

标准对话框

1.QMessageBox: 模态对话框,用于显示信息、询问问题等; 2.QColorDialog: 选择颜色; 3.QFontDialog: 选择字体; 4.QFileDialog: 选择文件或者目录; 5.QInputDialog: 允许用户输入一个值,并将其值返回; 6.QPageSetupDialog: 为打印机提供纸张相关的选项; 7.QPrintDialog: 打印机配置; 8.QPrintPreviewDialog:打印预览; 9.QProgressDialog: 显示操作过程

消息对话框
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
//About
void about(QWidget * parent, const QString & title, const QString & text)

//AboutQt

//Critical
StandardButton critical(QWidget * parent, 
const QString & title, 
const QString & text, 
StandardButtons buttons = Ok, 
StandardButton defaultButton = NoButton);

// Information
StandardButton information(QWidget * parent, 
const QString & title, 
const QString & text, 
StandardButtons buttons = Ok, 
StandardButton defaultButton = NoButton)

//Question
StandardButton question(QWidget * parent,
const QString & title, 
const QString & text, 
StandardButtons buttons = StandardButtons( Yes | No ), 
StandardButton defaultButton = NoButton) 

StandardButton warning(QWidget * parent, 
const QString & title, 
const QString & text, 
StandardButtons buttons = Ok, 
StandardButton defaultButton = NoButton)


QMessageBox msgBox;
msgBox.setText(tr("The document has been modified."));
msgBox.setInformativeText(tr("Do you want to save your changes?"));
msgBox.setDetailedText(tr("Differences here..."));
msgBox.setStandardButtons(QMessageBox::Save
                          | QMessageBox::Discard
                          | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Save);
int ret = msgBox.exec();
switch (ret) 
{
case QMessageBox::Save:
    qDebug() << "Save document!";
    break;
case QMessageBox::Discard:
    qDebug() << "Discard changes!";
    break;
case QMessageBox::Cancel:
    qDebug() << "Close document!";
    break;
}
标准文件对话框

布局

常用控件

QLable
1
2
3
4
5
6
7
QLable *label = new QLable;
label->setText(Hello, World!);

QLabel * label = new QLabel(this);
label ->setText("Hello, World");
label ->setText("<h1><a href=\"https://www.baidu.com\">百度一下</a></h1>");
label ->setOpenExternalLinks(true);
QLineEdit

EchoMode是一个枚举类型,一共定义了四种显示模式: 1.QLineEdit::Normal 模式显示方式,按照输入的内容显示。 2.QLineEdit::NoEcho 不显示任何内容,此模式下无法看到用户的输入。 3.QLineEdit::Password 密码模式,输入的字符会根据平台转换为特殊字符。 4.QLineEdit::PasswordEchoOnEdit 编辑时显示字符否则显示字符作为密码。 另外,我们再使用QLineEdit显示文本的时候,希望在左侧留出一段空白的区域,那么,就可以使用QLineEdit给我们提供的setTextMargins函数:

自定义控件

Qt消息事件机制

1.keyPressEvent():键盘按键按下事件 2.keyReleaseEvent():键盘按键松开事件 3.mouseDoubleClickEvent():鼠标双击事件 4.mouseMoveEvent():鼠标移动事件 5.mousePressEvent():鼠标按键按下事件 6.mouseReleaseEvent() :鼠标按键松开事件

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
class EventLabel : public QLabel
{
protected:
    void mouseMoveEvent(QMouseEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
};
 
void EventLabel::mouseMoveEvent(QMouseEvent *event)
{
    this->setText(QString("<center><h1>Move: (%1, %2)</h1></center>").arg(QString::number(event->x()),
                          QString::number(event->y())));
}
 
void EventLabel::mousePressEvent(QMouseEvent *event)
{
    this->setText(QString("<center><h1>Press:(%1, %2)</h1></center>").arg(QString::number(event->x()),
                          QString::number(event->y())));
}
 
void EventLabel::mouseReleaseEvent(QMouseEvent *event)
{
    QString msg;
    msg.sprintf("<center><h1>Release: (%d, %d)</h1></center>",
                event->x(), event->y());
    this->setText(msg);
}
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    
    EventLabel *label = new EventLabel;
    label->setWindowTitle("MouseEvent Demo");
    label->resize(300, 200);
    label->show();
    
    return a.exec();
}

label->setMouseTracking(true);

过滤器

绘图事件和绘图设备

QPainter
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
class PaintedWidget : public QWidget
{
    Q_OBJECT
public:
    PaintedWidget(QWidget *parent = 0);
protected:
    void paintEvent(QPaintEvent *);
}


PaintedWidget::PaintedWidget(QWidget *parent) :
    QWidget(parent)
{
    resize(800, 600);
    setWindowTitle(tr("Paint Demo"));
}
 
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);
}