[记录]Qt常用控件+事件+基础绘图
- 第一个Qt程序
新建一个空的项目
.pro文件内容
示例代码:
1 /* 应用程序抽象类 */ 2 #include <QApplication> 3 #include <QWidget> 4 #include <QPushButton> 5 #include <QDebug> 6 7 int main(int argc, char *argv[]) 8 { 9 QApplication app(argc, argv); 10 11 QWidget w; 12 w.show(); 13 w.setWindowTitle("你好,世界!"); // Qt 5不存在乱码的问题了 14 15 QPushButton btn("button"); 16 btn.setParent(&w); // 不设置父对象,那么按钮也就是一个独立的窗口 17 btn.show(); 18 19 QObject::connect(&btn, QPushButton::clicked, [](){ 20 qDebug() << "button is clicked..." << endl; 21 }); 22 23 return app.exec(); 24 }
- QLineEdit常用功能
设置输入密码
设置提示文字
设置自动匹配
示例代码:
1 #include <QApplication> 2 #include <QLineEdit> 3 #include <QDebug> 4 #include <QCompleter> 5 #include <QWidget> 6 7 int main(int argc, char *argv[]) 8 { 9 QApplication app(argc, argv); 10 11 QLineEdit lineEdit; 12 /* 显示模式 enum EchoMode { Normal, NoEcho, Password, PasswordEchoOnEdit }; */ 13 //lineEdit.setEchoMode(QLineEdit::PasswordEchoOnEdit); // 失去焦点时候变为密文 14 15 /* 淘汰传统的输入之后还要点击按钮 */ 16 QObject::connect(&lineEdit, QLineEdit::returnPressed, [](){ 17 qDebug() << "You have entered the return key..."; 18 }); 19 20 /* 自动补全 只有echomode设置为Normal时completer才有效 */ 21 QCompleter completer(QStringList() << "aa" << "abc" << "123"); 22 completer.setFilterMode(Qt::MatchContains); // 包含匹配 比如:输入b也会匹配abc 23 lineEdit.setCompleter(&completer); 24 25 /* lineEdit设置提示文字 */ 26 lineEdit.setPlaceholderText("Please input text:"); 27 28 lineEdit.show(); 29 30 return app.exec(); 31 }
- 坐标系统
设置坐标
1 #include <QApplication> 2 #include <QWidget> 3 #include <QPushButton> 4 5 int main(int argc, char* argv[]) 6 { 7 QApplication app(argc, argv); 8 9 /* 构造一个窗口*/ 10 QWidget w; 11 12 /*显示窗口*/ 13 w.show(); 14 15 /* 按钮也是个窗口 */ 16 QPushButton button; 17 button.setText("Button"); 18 /* 窗口对象的父子关系,影响显示位置 */ 19 /* 没有父窗口的窗口,我们称之为主窗口 */ 20 button.setParent(&w); 21 button.show(); 22 23 button.setGeometry(30, 30, 100, 30); 24 25 return app.exec(); 26 }
- 布局Layout
QHBoxLayout简单实现控件居中:
1 #include <QApplication> 2 #include <QWidget> 3 #include <QPushButton> 4 #include <QLineEdit> 5 #include <QHBoxLayout> 6 7 int main(int argc, char *argv[]) 8 { 9 QApplication app(argc, argv); 10 11 QWidget w; 12 QPushButton btn; 13 QLineEdit lineEdt; 14 btn.setText("button"); 15 16 QHBoxLayout hblyt; 17 /* 通过在左右添加弹簧使得控件在窗口中心 */ 18 hblyt.addStretch(1); // 最左边添加了弹簧 19 hblyt.addWidget(&btn); 20 hblyt.addWidget(&lineEdt); 21 /* 不希望lineedit随着窗口的变化而变化 */ 22 hblyt.addStretch(1); // 最右边添加了弹簧 23 w.setLayout(&hblyt); 24 w.show(); 25 26 return app.exec(); 27 }
效果图:
QHBoxLayout实现居中并且设置控件比重:
1 // 修改上面代码的下面部分即可 2 ... 3 /* 4 button和lineEdit比重都设置为1,还有两个弹簧, 5 那么它们占窗口宽度的四分之一 6 */ 7 hblyt.addWidget(&btn, 1); 8 hblyt.addWidget(&lineEdt, 1); 9 ...
效果图:
QGridLayout实现控件居中:
1 #include <QApplication> 2 #include <QWidget> 3 #include <QPushButton> 4 #include <QLineEdit> 5 #include <QHBoxLayout> 6 7 int main(int argc, char *argv[]) 8 { 9 QApplication app(argc, argv); 10 11 QWidget w; 12 QPushButton btn; 13 QLineEdit lineEdt; 14 btn.setText("button"); 15 16 QGridLayout glyt; 17 // 第0行设置一个弹簧,效果将控件弹到最底部 18 glyt.setRowStretch(0, 1); 19 // 再在最后一行设置一个弹簧,使得往上压,到了中部 20 glyt.setRowStretch(2, 1); 21 // 左右分别再设置列的弹簧,使控件左右也居中 22 glyt.setColumnStretch(0, 1); 23 glyt.setColumnStretch(3, 1); 24 glyt.addWidget(&btn, 1, 1); 25 glyt.addWidget(&lineEdt, 1, 2); 26 27 w.setLayout(&glyt); 28 w.show(); 29 30 return app.exec(); 31 }
效果图:
QGridLayout实现简单的登录界面:
1 #include <QApplication> 2 #include <QWidget> 3 #include <QPushButton> 4 #include <QLineEdit> 5 #include <QGridLayout> 6 #include <QHBoxLayout> 7 #include <QLabel> 8 9 int main(int argc, char *argv[]) 10 { 11 QApplication app(argc, argv); 12 13 QWidget w; 14 QPushButton loginBtn; 15 QLineEdit userEdt, passEdt; 16 QLabel userLabel, passLabel; 17 loginBtn.setText("登录"); 18 userLabel.setText("用户名:"); 19 passLabel.setText("密 码:"); 20 21 QGridLayout glyt; 22 glyt.setRowStretch(0, 1); 23 glyt.setColumnStretch(3, 1); 24 glyt.setRowStretch(4, 1); 25 glyt.setColumnStretch(0, 1); 26 glyt.addWidget(&userLabel, 1, 1); 27 glyt.addWidget(&userEdt, 1, 2); 28 glyt.addWidget(&passLabel, 2, 1); 29 glyt.addWidget(&passEdt, 2, 2); 30 /* 新加一个hboxLayout来让登录按钮右对齐且保持本身大小 */ 31 QHBoxLayout hblyt; 32 hblyt.addStretch(1); 33 hblyt.addWidget(&loginBtn); 34 glyt.addLayout(&hblyt, 3, 2); 35 36 w.setLayout(&glyt); 37 w.show(); 38 39 return app.exec(); 40 }
效果图:
- 常用控件的基本使用
QLabel
1 // QLabel 简单使用 2 #include <QApplication> 3 #include <QWidget> 4 #include <QLabel> 5 #include <QDebug> 6 #include <QUrl> 7 #include <QDesktopServices> 8 9 int main(int argc, char *argv[]) 10 { 11 QApplication app(argc, argv); 12 13 QWidget w; 14 QLabel label(&w); 15 // label添加具有html样式的文字 16 label.setText("<a href=http://www.baidu.com>百度一下</a>"); 17 /* 实现打开链接的两种方式 */ 18 // 1.本身添加了链接是不打开的,可以通过以下函数实现打开 19 // label.setOpenExternalLinks(true); 20 // 2.添加linkActivated信号处理 21 QObject::connect(&label, QLabel::linkActivated, [](const QString &link){ 22 QUrl url; 23 url.setUrl(link); 24 QDesktopServices::openUrl(url); 25 }); 26 // label添加图片 27 // label.setPixmap(QPixmap("../demo.png")); 28 w.show(); 29 30 return app.exec(); 31 }
Button组(QPushButton,QRadioButton, QCombobox,QCheckBox)
1 // Button组 简单使用 2 #include <QApplication> 3 #include <QWidget> 4 #include <QDebug> 5 #include <QPushButton> 6 #include <QRadioButton> 7 #include <QComboBox> 8 #include <QCheckBox> 9 #include <QVBoxLayout> 10 #include <QHBoxLayout> 11 #include <QCompleter> 12 13 int main(int argc, char *argv[]) 14 { 15 QApplication app(argc, argv); 16 17 QWidget w; 18 QPushButton btn; 19 QRadioButton rbtn1("男性"), rbtn2("女性"), rbtn3("中性"); 20 QComboBox combobox; 21 QCheckBox ckbox1("c语言"), ckbox2("C++"), ckbox3("Java"); 22 QVBoxLayout vblyt(&w); 23 QHBoxLayout hblyt1, hblyt2; 24 25 // QPushButton 26 btn.setText("Button"); 27 btn.setDefault(true); // 设置为默认按钮 28 btn.setStyleSheet("color: red"); 29 // setDefault 空格和回车都有效 30 QObject::connect(&btn, QPushButton::clicked, [](){ 31 qDebug() << "button is clicked"; 32 }); 33 34 // QRadioButton 35 // ps : 添加了多个Radio,默认就是只支持选择一个的 36 QObject::connect(&rbtn1, QRadioButton::clicked, [](){ 37 qDebug() << "rbtn1 is selected"; 38 }); 39 QObject::connect(&rbtn2, QRadioButton::clicked, [](){ 40 qDebug() << "rbtn2 is selected"; 41 }); 42 QObject::connect(&rbtn3, QRadioButton::clicked, [](){ 43 qDebug() << "rbtn3 is selected"; 44 }); 45 46 // QComboBox 47 combobox.addItem("select item1"); 48 combobox.addItem("select item2"); 49 // 设置可编辑,一旦按下回车,就会addItem你写入的数据 50 combobox.setEditable(true); 51 // 设置自动补全 52 combobox.setCompleter(new QCompleter(combobox.model())); 53 // 信号函数存在重载的解决方案1,2 54 /*void (QComboBox:: *sig)(const QString &) = &QComboBox::currentIndexChanged; 55 QObject::connect(&combobox, sig, [](const QString &str){ 56 qDebug() << str; 57 });*/ 58 QObject::connect( 59 &combobox, 60 static_cast<void (QComboBox:: *)(const QString &)> (&QComboBox::currentIndexChanged), 61 [](const QString &str){ 62 qDebug() << str; 63 }); 64 65 // QCheckBox 66 QObject::connect(&ckbox1, &QCheckBox::clicked, [](bool b){ 67 qDebug() << b << "chkbox1"; 68 }); 69 QObject::connect(&ckbox2, &QCheckBox::clicked, [](bool b){ 70 qDebug() << b << "ckbox2"; 71 }); 72 QObject::connect(&ckbox3, &QCheckBox::clicked, [](bool b){ 73 qDebug() << b << "ckbox3"; 74 }); 75 76 hblyt1.addWidget(&rbtn1); 77 hblyt1.addWidget(&rbtn2); 78 hblyt1.addWidget(&rbtn3); 79 80 hblyt2.addWidget(&ckbox1); 81 hblyt2.addWidget(&ckbox2); 82 hblyt2.addWidget(&ckbox3); 83 84 vblyt.addWidget(&btn); 85 vblyt.addLayout(&hblyt1); 86 vblyt.addWidget(&combobox); 87 vblyt.addLayout(&hblyt2); 88 89 w.show(); 90 91 return app.exec(); 92 }
效果图:
QTextEdit基本使用:1 int main(int argc, char *argv[]) 2 { 3 QApplication app(argc, argv); 4 5 QWidget w; 6 QTextEdit textEdit(&w); 7 textEdit.setText("<table border=1>" 8 "<tr><th>I'm title</th></tr>" 9 "<tr><td>数据1</td><td>数据2</td></tr>" 10 "</table>" 11 "<img src=../demo.png>"); 12 13 QObject::connect(&textEdit, &QTextEdit::textChanged, [](){ 14 qDebug() << "Do you save it?"; 15 }); 16 17 // 设置滚动条 18 textEdit.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 19 textEdit.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 20 21 w.show(); 22 23 return app.exec(); 24 }
效果图:
QGroupBox基本使用:
1 // QGroupBox 简单使用 2 #include <QApplication> 3 #include <QWidget> 4 #include <QDebug> 5 #include <QPushButton> 6 #include <QGroupBox> 7 #include <QVBoxLayout> 8 9 int main(int argc, char *argv[]) 10 { 11 QApplication app(argc, argv); 12 13 QWidget w; 14 QGroupBox group(&w); 15 QVBoxLayout vblyt; 16 QPushButton btn1("btn1"), btn2("btn2"); 17 18 vblyt.addWidget(&btn1); 19 vblyt.addWidget(&btn2); 20 group.setLayout(&vblyt); 21 group.setTitle("按钮"); 22 23 w.show(); 24 25 return app.exec(); 26 }
效果图:
QSlider、QSpinBox基本使用:
1 // QSlider QSpinBox 简单使用 2 #include <QApplication> 3 #include <QWidget> 4 #include <QDebug> 5 #include <QVBoxLayout> 6 #include <QSpinBox> 7 #include <QSlider> 8 9 int main(int argc, char *argv[]) 10 { 11 QApplication app(argc, argv); 12 13 QWidget w; 14 QVBoxLayout vblyt(&w); 15 16 QSlider slider; 17 QSpinBox spinBox; 18 19 slider.setMaximum(100); 20 slider.setMinimum(0); 21 spinBox.setMaximum(100); 22 spinBox.setMinimum(0); 23 24 QObject::connect(&slider, &QSlider::valueChanged, &spinBox, &QSpinBox::setValue); 25 // 注意SpinBox的valueChaged信号重载了 26 QObject::connect(&spinBox, static_cast<void (QSpinBox:: *)(int)>(&QSpinBox::valueChanged), &slider, &QSlider::setValue); 27 vblyt.addWidget(&slider); 28 vblyt.addWidget(&spinBox); 29 30 w.show(); 31 32 return app.exec(); 33 }
效果图:
QLCDNumber基本使用:
1 // QLCDNumber 简单使用 2 #include <QApplication> 3 #include <QWidget> 4 #include <QDebug> 5 #include <QVBoxLayout> 6 #include <QLCDNumber> 7 8 int main(int argc, char *argv[]) 9 { 10 QApplication app(argc, argv); 11 12 QWidget w; 13 QLCDNumber number(10, &w); 14 number.display(123.456); 15 // 设置显示模式 16 number.setMode(QLCDNumber::Bin); 17 number.setSegmentStyle(QLCDNumber::Outline); 18 w.show(); 19 20 return app.exec(); 21 }
效果图:
- QEvent
1 #ifndef MYWIDGET_H 2 #define MYWIDGET_H 3 4 #include <QWidget> 5 6 class MyWidget : public QWidget 7 { 8 Q_OBJECT 9 public: 10 explicit MyWidget(QWidget *parent = 0); 11 bool event(QEvent *); 12 void mousePressEvent(QMouseEvent *); 13 void mouseMoveEvent(QMouseEvent *); 14 void mouseReleaseEvent(QMouseEvent *); 15 16 void keyPressEvent(QKeyEvent *); 17 void keyReleaseEvent(QKeyEvent *); 18 19 void paintEvent(QPaintEvent *); 20 void closeEvent(QCloseEvent *); 21 22 signals: 23 24 public slots: 25 }; 26 27 #endif // MYWIDGET_H
1 #include "MyWidget.h" 2 #include <QDebug> 3 #include <QEvent> 4 #include <QMouseEvent> 5 #include <QKeyEvent> 6 #include <QPaintEvent> 7 #include <QPainter> 8 9 MyWidget::MyWidget(QWidget *parent) : QWidget(parent) 10 { 11 // 不需要左键按下,mouseMove事件能发生 12 setMouseTracking(true); 13 } 14 15 // 事件截取 16 bool MyWidget::event(QEvent *ev) 17 { 18 if (ev->type() == QEvent::MouseButtonPress) 19 { 20 qDebug() << "mouse button press"; 21 } 22 23 return QWidget::event(ev); 24 } 25 26 // 鼠标事件处理 27 void MyWidget::mousePressEvent(QMouseEvent *ev) 28 { 29 // 得到坐标 30 //qDebug() << ev->pos(); 31 // 判断左键 + 按住cntrl键 32 if (ev->button() == Qt::LeftButton && 33 ev->modifiers() == Qt::ControlModifier) { 34 qDebug() << "开始复选"; 35 } 36 } 37 38 void MyWidget::mouseMoveEvent(QMouseEvent *ev) 39 { 40 static int i = 0; 41 qDebug() << ev->pos() << " mouse move: " << i++; 42 } 43 44 void MyWidget::mouseReleaseEvent(QMouseEvent *ev) 45 { 46 qDebug() << ev->pos(); 47 } 48 49 // 按键事件 50 void MyWidget::keyPressEvent(QKeyEvent *ev) 51 { 52 // 只能打印出大写 53 qDebug() << static_cast<char>(ev->key()); 54 } 55 56 void MyWidget::keyReleaseEvent(QKeyEvent *) 57 { 58 59 } 60 61 void MyWidget::paintEvent(QPaintEvent *) 62 { 63 QPainter p(this); 64 p.drawLine(QPoint(0, 0), QPoint(100, 100)); 65 } 66 67 void MyWidget::closeEvent(QCloseEvent *) 68 { 69 qDebug() << "close window"; 70 } 71 72 #include <QApplication> 73 74 int main(int argc, char *argv[]) 75 { 76 QApplication app(argc, argv); 77 78 MyWidget w; 79 w.show(); 80 81 82 return app.exec(); 83 }
- EventFilter
1 #ifndef MYAPPLICATION_H 2 #define MYAPPLICATION_H 3 4 #include <QApplication> 5 6 class MyApplication : public QApplication 7 { 8 public: 9 MyApplication(int argc, char *argv[]); 10 bool notify(QObject *, QEvent *); 11 }; 12 13 #endif // MYAPPLICATION_H
1 #include "MyApplication.h" 2 #include <QDebug> 3 4 MyApplication::MyApplication(int argc, char *argv[]) : 5 QApplication(argc, argv) 6 { 7 8 } 9 10 bool MyApplication::notify(QObject *o, QEvent *e) 11 { 12 if (topLevelWidgets().count() > 0) { 13 QWidget *mainWnd = topLevelWidgets().at(0); 14 if (o == (QObject *)mainWnd && 15 e->type() == QEvent::MouseButtonPress) { 16 qDebug() << "Mian Window is clicked."; 17 } 18 } 19 20 return QApplication::notify(o, e); 21 }
1 #ifndef MYWIDGET_H 2 #define MYWIDGET_H 3 4 #include <QWidget> 5 class QPushButton; 6 7 class MyWidget : public QWidget 8 { 9 Q_OBJECT 10 public: 11 explicit MyWidget(QWidget *parent = 0); 12 bool eventFilter(QObject *, QEvent *); 13 bool event(QEvent *); 14 QPushButton *_btn; 15 16 signals: 17 18 public slots: 19 }; 20 21 #endif // MYWIDGET_H
1 #include "MyWidget.h" 2 #include <QPushButton> 3 #include <QEvent> 4 #include <QDebug> 5 #include <QMouseEvent> 6 7 MyWidget::MyWidget(QWidget *parent) : QWidget(parent) 8 { 9 _btn = new QPushButton("Button", this); 10 _btn->installEventFilter(this); 11 } 12 13 bool MyWidget::eventFilter(QObject *o, QEvent *e) 14 { 15 if (o == (QObject *)_btn && ( 16 e->type() == QEvent::MouseButtonPress || 17 e->type() == QEvent::MouseButtonRelease /*|| 18 e->type() == QEvent::MouseButtonDblClick*/)) { 19 qDebug() << "button is clicked."; 20 return true; 21 } 22 23 return QWidget::eventFilter(o, e); 24 } 25 26 bool MyWidget::event(QEvent *ev) 27 { 28 if (ev->type() == QEvent::User) { 29 qDebug() << "user self-define event."; 30 } 31 return QWidget::event(ev); 32 } 33 34 #include "MyApplication.h" 35 36 int main(int argc, char *argv[]) 37 { 38 MyApplication app(argc, argv); 39 40 MyWidget w; 41 w.show(); 42 43 /* 44 Start 45 End 46 user self-define event. 47 */ 48 /* 49 qDebug() << "Start"; 50 app.postEvent(&w, new QEvent(QEvent::User)); // post只是发消息过去,而send是发完了返回了才往下执行 51 qDebug() << "End"; 52 */ 53 54 qDebug() << "Start"; 55 app.sendEvent(&w, new QEvent(QEvent::User)); 56 qDebug() << "End"; 57 58 return app.exec(); 59 }
- QPainter
覆盖基类的painterEvent虚函数,函数原型为:
简单的图形绘制:
1 void MyWidget::paintEvent(QPaintEvent *) 2 { 3 // 简单的绘制 4 QPainter p(this); 5 //p.drawArc(100, 100, 20, 20, 10, 10); 6 p.drawLine(QPointF(100, 100), QPointF(200, 200)); 7 p.setPen(QPen(QColor("red"))); 8 p.setBrush(Qt::yellow); // 画刷是代表封闭图形的内部填充 9 p.drawRect(QRect(200, 200, 220, 220)); 10 p.setRenderHint(QPainter::Antialiasing); // 变得圆润一些 11 p.drawEllipse(QPointF(150, 150), 40, 40); 12 p.drawText(QPointF(250, 250), "Hello Qt"); 13 }
通过变换集来存储所有的变换:
1 { 2 // 通过变换集来存放所有的变换 3 QPainter p(this); 4 QTransform trans; 5 //trans.rotate(88.0, Qt::YAxis); 6 //trans.translate(100, 300); 7 trans.scale(3, 3); 8 p.setTransform(trans); 9 p.drawLine(100, 100, 200, 100); 10 }
先画一张图,然后将该图绘制到窗口上:
1 { 2 // 先画一张图,然后将图绘制到窗口 3 QPixmap pixmap(size()); // pixmap默认的是黑色背景 4 QPainter p(&pixmap); 5 6 // 想着设置pixmap背景为白色,并不能实现,需要通过以下方法 7 //p.setBackground(QBrush(Qt::white)); 8 p.setBrush(Qt::white); 9 p.drawRect(0, 0, size().width(), size().height()); 10 p.drawLine(QPointF(100, 100), QPointF(200, 200)); 11 p.setPen(QPen(QColor("red"))); 12 p.setBrush(Qt::yellow); // 画刷是代表封闭图形的内部填充 13 p.drawRect(QRect(200, 200, 220, 220)); 14 15 p.end(); 16 p.begin(this); // 开始绘制窗口 17 p.drawPixmap(0, 0, pixmap); 18 }