QT
#include "mainwindow.h"
#include "ui_mainwindow.h"
#
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
setWindowTitle("Restaurant");
resize(600,400);
//setFixedSize(1200,1500);
ui->setupUi(this);
QPushButton *btn1 = new QPushButton;
btn1->setParent(this);
btn1->setText("login");
btn1->setFixedSize(60,60);
btn1->move(0,40);
}
MainWindow::~MainWindow()
{
delete ui;
}
按鈕 指定了父類之後不用自己刪掉,會被放到表裏被釋放掉
//點擊窗口觸發行爲
//槽函數
//參數:發送者(按鈕) 信號(函數地址) 接收者(窗口) 槽函數
connect(btn1,&QPushButton::clicked,this,&MainWindow::close);
自定義出發信號類和函數
老師類.h
#include <QObject>
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
signals:
// 自定義信號 寫道siginals下,可以有參數,可以重載
void hungry();// 返回值是void, 只需要聲明,不需要實現
public slots:
};
學生類.h
#include <QObject>
class Student : public QObject
{
Q_OBJECT
public:
explicit Student(QObject *parent = nullptr);
signals:
public slots:
// 學生類需要對老師餓了的信號做出響應
// 返回值void,需要聲明,也需要實現
// 可以有參數,可以發生重載
void treat();
};
學生類.cpp
#include "student.h"
#include <QDebug>
Student::Student(QObject *parent) : QObject(parent){}
void Student::treat(){
qDebug() << "treat the teacher";
}
mainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->te = new Teacher(this);
this->st = new Student(this);
//連接老師和學生的信號
connect(te,&Teacher::hungry,st,&Student::treat);
// 調用下課函數,觸發信號
classisOver();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::classisOver(){
// 下課函數,觸發老師餓了的信號
emit te->hungry();
}
參數重載的情況
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->te = new Teacher(this);
this->st = new Student(this);
//連接老師和學生的信號
//connect(te,&Teacher::hungry,st,&Student::treat);
// 定義函數指針,指向有參的函數
void (Teacher:: *tesignal)(QString) = &Teacher::hungry;
void (Student:: *stuslot)(QString) = &Student::treat;
connect(te,tesignal,st,stuslot);
// 調用下課函數,觸發信號
classisOver();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::classisOver(){
// 下課函數,觸發老師餓了的信號
emit te->hungry("icecream");
}
將QString轉爲Char *
打印的時候QString會自帶引號,需要進行轉化
void Student::treat(QString foodName){
//先轉QByteArray(.toUtf8()),再轉char*(.data())
qDebug()<<"treat the teacher "<<foodName.toUtf8().data();
}
按鈕觸發函數
\ //點擊一個下課按鈕出發下課
QPushButton *btn = new QPushButton("overclass",this);
btn->resize(50,50);
btn->move(100,100);
connect(btn,&QPushButton::clicked,this,&MainWindow::classisOver);
按鈕連接到觸發函數上,觸發函數觸發信號,老師發出餓了的信號,啓動老師和學生之間的連接,觸發學生招待的行爲
信號連接信號,不通過函數觸發。
//信號連接信號
void (Student:: *stuslot2)(void) = &Student::treat;
void (Teacher:: *tesignal2)(void) = &Teacher::hungry;
connect(btn,&QPushButton::clicked,te,tesignal2);
connect(te,tesignal2,st,stuslot2);
一個信號可以連接多個槽函數
多個信號可以連接同一個槽函數
信號和槽函數的參數必須一一對應
信號的參數可以多於槽函數的參數數量
斷開信號
//斷開信號
disconnect(btn,&QPushButton::clicked,te,tesignal2);
lambda表達式
[](){}();
[=](){btn->settext("Hello")}(); //值傳遞方式,可以用lambda所在作用域範圍內所有可見的局部變量
[&](){btn->settext("Hello")}(); //引用傳遞方式
[btn](){btn->settext("Hello")}();//只允許看到btn
int m;
connect(btn,&QPushButton::clicked,this,[m]() mutable {m=100+10;qDebug()<<m;});
//如果想修改按值傳遞進來的拷貝就需要加上mutable,但是這樣也不會修改到本體
int ret = []()->int{return 1000}(); //設置返回值類型
//點擊按鈕關閉窗口
QPushButton *btn2 = new QPushButton;
btn2->setParent(this);
btn2->setText("Close");
connect(btn2,&QPushButton::clicked,this,[this](){this->close();});
QMainWindow
Menu Bar
Tool Bar Area
Dock Widget Area : 可拖動的欄
Central Widget
Status Bar
菜單欄和工具欄設置
//設置菜單欄
QMenuBar *mbar = menuBar();
setMenuBar(mbar);
QMenu *sign = mbar->addMenu("sign");
QMenu *mag = mbar->addMenu("manage");
//創建菜單項
QAction *signin = sign->addAction("signin");
sign->addAction("signup");
QAction *rep = mag->addAction("reception");
mag->addSeparator();
QAction *bak = mag->addAction("backstage");
//設置工具欄
QToolBar * toolbar = new QToolBar(this);
addToolBar(toolbar);
/*設置工具欄項目
toolbar->addAction(signin);
toolbar->addSeparator();
toolbar->addAction(bak);*/
QPushButton *btn1 = new QPushButton("signin");
toolbar->addWidget(btn1);
狀態欄設置
//創建狀態欄
QStatusBar *stbar = statusBar();
setStatusBar(stbar);
//添加標籤控件
QLabel *label1 = new QLabel("Restaurant management system",this);
stbar->addWidget(label1);
浮動窗口和中心部件設置
//創建浮動窗口
QDockWidget *dw = new QDockWidget("flow",this);
addDockWidget(Qt::BottomDockWidgetArea,dw);
//設置中心部件.
QTextEdit * edit = new QTextEdit(this);
setCentralWidget(edit);
添加資源
//ui->actiond_2->setIcon(QIcon("C:\\Users\\vr2019\\Pictures\\3.jpg"));
//添加QT資源到項目,需要先把圖片目錄複製到工程下
//然後右鍵項目, 添加新文件,選擇模板QT下的QT resource file,獲得qrc文件
//進入qrc文件需要右鍵添加資源
//首先要添加前綴比如裝備、首飾做區分
//然後編譯一下,文件就放進去了
//添加qt資源圖片":加前綴名和文件名"
設置背景樣式表和自適應
QWidget#centralWidget{border-image:url(:/images/00.jpg);background-size:100% 100%;}
模態對話框和非模態對話框
//點擊登錄按鈕 彈出一個對話框
connect(ui->action11,&QAction::triggered,this,[=](){
// 彈出對話框#include "QDialog"
// 對話框分類:
// 模態對話框:創建後不可以操作其他窗口
QDialog dig(this);
dig.resize(200,100);
dig.exec(); //相當於阻塞
// 非模態對話框:創建後,可以操作其它窗口
// 因爲之後還可以創建其他窗口,所以需要放在堆上
QDialog *dlg= new QDialog(this);
dlg->resize(200,100);
dlg->setAttribute(Qt::WA_DeleteOnClose);// 防止內存泄漏
dlg->show();
});
標準對話框
系統內置了一系列對話框
QColorDialog:選擇顏色
QFileDialog:選擇文件或者目錄
QFontDialog:選擇字體
QInputDialog:允許用戶輸入一個值並返回
QMessageBox:模態對話框,用於顯示信息,詢問問題等
QPageSetupDialog:爲打印機提供紙張相關的選項
QPrintDialog:打印機配置
QPrintPreviewDialog:打印預覽
QProgressDialog:顯示操作過程
自定義消息框QMessageBox
//點擊登錄按鈕 彈出消息對話框
connect(ui->action11,&QAction::triggered,this,[=](){
//自定義消息對話框
//錯誤對話框
QMessageBox::critical(this,"critital","錯誤");
//信息對話框
QMessageBox::information(this,"info","信息");
//警告對話框
QMessageBox::warning(this,"warn","警告");
//question對話框,參數:父,窗口名,內容,選項,默認設置的選項
QMessageBox::StandardButton resl = QMessageBox::question(this,"ques","提問",QMessageBox::Save|QMessageBox::Cancel,QMessageBox::Cancel);
//如何得知用戶點了save
if(resl == QMessageBox::Save){
qDebug()<<"執行保存操作";
}
});
顏色對話框
//打開顏色對話框,並設置默認值和透明度
QColor color = QColorDialog::getColor(QColor(255,0,0));
qDebug()<<"r= "<<color.red();
qDebug()<<"g= "<<color.green();
qDebug()<<"b= "<<color.blue();
文件對話框
//打開文件對話框
//返回值:文件路徑 參數:父類,窗口標題,默認打開路徑,過濾文檔(只看得到txt文件)
QString str = QFileDialog::getSaveFileName(this,"打開文件","C:\\Users\\vr2019\\Desktop","(*.txt)");
qDebug()<<str;
字體設置對話框
//字體設置對話框
//參數:bool值,默認字體和字號設置,返回值:選擇的字號和字體
bool flag;
QFont font = QFontDialog::getFont(&flag,QFont("Arial",36));
qDebug()<<"font:"<<font.family().toUtf8().data();
qDebug()<<"fontsize:"<<font.pointSize();
觸發新窗口
https://blog.csdn.net/m0_37143327/article/details/80265820
頁面佈局(登錄界面設置)
把組件移動到水平分佈的框裏即可水平對齊
更推薦移動Containers的widget框內,再進行水平或垂直對齊
控制間距用Spacers,可以設置其大小來改變間距,條件(佈局)
佈局過的窗口會很大,可以通過sizePolicy來縮小空白間隔 Fixed
固定大小:設置最大和最小值一樣
密碼輸入設爲暗紋:label屬性設置echoMode改爲Password
控件
PushButton 添加資源圖片用icon圖標
toolbutton:主要是添加圖片用,文字和圖片一起顯示 :lButtonStyle, 選中效果:autoraise
RadioButton:單選按鈕設置:把radiobutton拖到groupbox裏,默認值設置
//默認值設置,選中一個默認的radiobutton
ui->name->setchecked(true);
監聽選項
connect(ui->name,&QRadioButtion::clicked,[=](){操作});
CheckBox:多選按鈕
ui->name->setchecked(true);
//2是選中,0是未選中。1是半選,需要選中tristate屬性纔可以有半選
connect(ui->name,&QRadioButtion::stateChanged,[=](int state){操作});
ListView: 文本框
QListWidgetItem *item = new QListWidgetItem("the first line");
ui->listWidget->addItem(item);
item->setTextAlignment(Qt::AlignCenter); //設置水平居中
// QStringList
QStringList list;
list << "the second line" <<"the thrid line"; //連續輸入
ui->listWidget->addItems(list);
TreeWidget:目錄樹
// 設置水平標籤頭
ui->treeWidget->setHeaderLabels(QStringList()<<"Hero"<<"HeroIntro");
QTreeWidgetItem *stritem = new QTreeWidgetItem(QStringList()<<"Strength");
QTreeWidgetItem *stritem1 = new QTreeWidgetItem(QStringList()<<"Quick");
QTreeWidgetItem *stritem2 = new QTreeWidgetItem(QStringList()<<"Smart");
//添加頂層結點
ui->treeWidget->addTopLevelItem(stritem);
ui->treeWidget->addTopLevelItem(stritem1);
ui->treeWidget->addTopLevelItem(stritem2);
//追加子節點
QStringList hero1;
hero1 << "cai wen ji" <<"help partners restore health";
QTreeWidgetItem *l1 = new QTreeWidgetItem(hero1);
stritem->addChild(l1);
TableWidget :表
//設置列數和行數
ui->tableWidget->setColumnCount(3);
ui->tableWidget->setRowCount(5);
//設置水平表頭
ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<"Name"<<"Gender"<<"Age");
//在表中加入內容
QStringList nameList;
nameList << "apple"<<"banana" << "pear";
for(int i =0;i<3;i++){
ui->tableWidget->setItem(0,i,new QTableWidgetItem(nameList[i]));
}
其他控件
ScrollArea :滾動區域,東西拖進來排列之後可以滾動
ToolBox:類似於QQ中聯繫人,朋友,家人,黑名單等分類方式
TabWidget:類似於瀏覽器的標籤頁
StackedWidget:可以切頁。設計中可以按箭頭切換,但是在運行中需要定義按鈕和信號槽來切換頁面
ui->stackedWidget->setCurrentIndex(2); // 設置默認值
connect(ui->btn_scrollArea,&QPushButton::clicked,[=](){
ui->stackedWidget->setCurrentIndex(0);
});
connect(ui->btn_ToolBox,&QPushButton::clicked,[=](){
ui->stackedWidget->setCurrentIndex(1);
});
ComboBox:下拉框
ui->comboBix->addItem("AWM");
ui->comboBix->addItem("m416");
ui->comboBix->addItem("98k");
connect(ui->btn_select,&QPushButton::clicked,[=](){
ui->comboBox->setCurrentIndex(2); //點一下按鈕設爲默認值
});
QLable:文本框,可用於圖片顯示,以及動圖顯示
//利用QLabel顯示圖片,
ui->qlable->setPixmap(":/image/butterfly.png");
//利用QLabel顯示動圖
QMovie *movie = new QMovie(":/img/imh.gif");
ui->qlable->setMovie(movie);
movie->start();
ProgressBar:進度條
自定義控件
自己進行封裝操作:
添加新文件,Qt設計師界面類,選擇模板Widget空窗口。 進行設計。設計完之後在主窗口界面上,放一個Widget,右鍵提升爲這個自定義類,點擊全局包含和提升,widget變爲自定義的控件
例子
//SpinBox移動 QSlider跟着移動
void(QSpinBox:: * spSignal)(int) = &QspinBox::valuechanged;
connect(ui->spinBox,spSignal,ui->slider,&Qslider::setValue);
connect(ui->slider,&Qslider::valuechanged,ui->spinBox,&QpinBox::setValue);
QT事件
鼠標事件
QEnterEvent鼠標進入捕獲的
//自定義控件類,在頭文件上寫
void enterEvent(QEvent *event);
void leaveEvent(QEvent *event);
//在源文件上寫
void Mylabel::enterEvent(QEvent *event) //重載鼠標事件
{
qDebug() <<"鼠標進入了";
}
void Mylabel::leaveEvent(QEvent *event)
{
qDebug() <<"鼠標離開了";
}
//在主界面上放一個QLable,右鍵提升爲自定義控件就可以捕捉到事件
//設置QFrame看到框的邊界、
//鼠標事件
void enterEvent(QEvent *event);
void leaveEvetn(QEvent *);
void mousePressEvent(QMouseEvent *ev){
QString str = QString("鼠標按下了,x=%1,y=%2").arg(ev->x()).arg(ev->y());
qDebug()<<str; //座標是基於框的
QString str = QString("鼠標按下了,x=%1,y=%2").arg(ev->x()).arg(ev->y());
qDebug()<<str; //座標是基於框的,獲取全局的ev->globalx()
if(ev->button()==Qt::LeftButton){ //鼠標左鍵按下
qDebug()<<"鼠標左鍵釋放了";
}
}
void mouseReleaseEvent(QMouseEvent *ev){
}
void mouseMoveEvent(QMouseEvent *ev){
//ev->buttons()
if(ev->buttons() & Qt::LeftButton ){區分移動的情況}
}
//在類中設置setMousetracking(true);進行鼠標追蹤爲真,只要一移動就可以捕獲情況
定時器事件(用第二種方法做)
//在類中重寫定時器事件
void timerEvent(QTimerEvent *ev){
if(ev->timerId()==id1){
static int num = 1;
ui->label1->setText(QString::number(num++));
}
if(ev->timerId()==id2){
static int num = 10;
ui->label1->setText(QString::number(num++));
}
}
//在Wdiget中定時器事件,參數:間隔(毫秒單位),
int id1 = startTimer(1000);
int id2 = startTimer(2000);
//如果寫了兩個怎麼區分是用哪個定時器調用的
//第二種方法
QTimer * timer = new QTimer(this);
timer->start(500);
connect(timer,&QTimer::timeout,[=](){
static int num=1;
ui->label->setText(QString::numebr(num++);)
});
//如果兩個定時器就new倆,最好用第二種定時器的方法
//點擊暫停按鈕,停止定時器
connnect(ui->btn,&QPushButton::clicked,[=](){
timer->stop();
});
通過事件分發器攔截事件()
主要說明event分發事件的功能,不建議用來做攔截操作
bool myLabel::event(QEvent *e)
{
//如果是鼠標按下,在event事件分發中做攔截操作
if(e->type()==QEvent::MouseButtonPress){
QString str= QString("巴拉巴拉");
qDebug()<<str;
return true;//代表該類自己處理鼠標按下事件,不向下分發,
//也就是myLabel::MouseButtonPress()函數不會被觸發
}
//其他事件, 交給父類處理
return QLable:event(e);
}
事件過濾器
通過事件過濾器,可以在程序分發到event事件之前在做一次高級攔截
使用步驟:
- 給控件安裝事件過濾器
- 重寫eventfilter事件
封裝:
release目錄下有:.exe + 保證qt目錄下有:windeployqt
新建目錄,放入exe文件,運行windeployqt bvala.exe