日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Qt学习心得

發布時間:2024/1/1 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt学习心得 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

Qt特性

Qt核心特點

Qt容器

Qt快捷鍵

Qt類庫模塊

Qt控件的使用

QSpinBox、QDoubleSpinBox

QTextEdit

進度條

時間控件

QPlainTextEdit

QComBox

QListWidget

QTreeWidget

QtableWidget

Model、View結構

QFileSystemModel

QStringListModel

QStandardItemModel

QItemSelectionModel

自定義代理

Qt對話框

QFileDialog

QColorDialog

QFontDialog

字符輸入對話框

整形輸入對話框

浮點數輸入對話框

條目輸入對話框

Question消息框

information消息框

warning消息框

critical消息框

about消息框

自定義對話框及調用

多窗體應用程序設計

SPlash和登錄窗口

文本文件讀寫

QFile IODevice讀寫文件

QTextSteam讀寫文件

解決漢字亂碼問題

二進制文件讀寫

使用QDataStream讀寫stm類型文件

使用QDataStream讀寫dat類型文件

使用DataStream讀取.dat文件

文件目錄操作

QPainter基本繪制

坐標系統和坐標轉換

視口坐標和窗口坐標

QtCharts

Qtchart繪制折線圖???????

QBarChart

繪制餅狀圖(QPieChart)

繪制堆積圖(QStackedBar)

繪制散點圖(Scatterchart)

Qt特性

Qt核心特點

元對象編譯器(Meta-Object Compiler,MOC)是一個預處理器 先將Qt的特性程序轉換為標準C++程序,在由標準C++編譯器進行編譯

使用信號與槽機制,只有添加Q_OBJECT宏,moc才能對類里的信號與槽進行預處理

Qt為C++語言增加的特性在Qt Core模塊里實現,由Qt的元對象系統實現。 包括:信號與槽機制、屬性系統、動態類型轉換等。

元對象系統(Meta-Object System)

QObject類是所有使用元對象系統的類的基類 在一個類的private部分聲明Q_OBJECT宏 MOC(元對象編譯器)為每個QObject的子類提供必要的代碼

可以使用Qobject對象對Qt的控件進行控制

QObject *obj = new QMyWidget; QWidget *widget = qobject_cast<QWidget *>(obj); QMyWidget *myWidget = qobject_cast<QMyWidget *>(obj); QLabel *label = qobject_cast<QLabel *>(obj); //不會報錯,label為NULL

qobject_cast<QWidget *> 為類型轉換,加了之前就相當于調用了指向QWidget的指針,可以對QWidget進行操作

qobject_cast<QLabel *>(obj);//obj原本指向QWidget,但使用QLabel對其進行指向,QWidget不包含QWidget的內容,因此返回的東西為Null;

Q_PROPERTY宏定義一個返回類型為type,名稱為name的屬性

class TestWidget : public QWidget {Q_OBJECTQ_CLASSINFO("author", "liu") }; ? ?TestWidget * test = new TestWidget;qDebug() << test->metaObject()->classInfo(0).name();qDebug() << test->metaObject()->classInfo(0).value();

QClassInfo可以記錄類的附加信息,通過metaobject進行調用獲取

Qt容器

QMap是鍵值對關系 key不能重復 QMultiMap的key可以重復

QHash 和 QMap的區別 : QMap是連續存儲的,里面的值也是按順序存儲的 QHash里面的值不一定是按順序存儲的,而是按映射存儲的

QSet是基于散列表的

C++ Map是STL的一個關聯容器,它提供一對一(其中第一個可以稱為關鍵字,每個關鍵字只能在map中出現一次,第二個可能稱為該關鍵字的值) 對于迭代器來說,可以修改實值,而不能修改key

C++vector容器的定義 vector<int>::iterator i; //定義正向迭代器

vector<int>::reverse_iterator j; //用反向迭代器遍歷容器

Qt快捷鍵

F4 頭文件和cpp進行切換 F2定義和實現之間進行切換 F1光標所在的符號顯示幫助

Qt類庫模塊

其他模塊都依賴于Qt Core模塊,使用 qmake 構建,此模塊會自動被加入項目 QT -= gui qmake 構建時,Qt GUI 模塊是自動被加入項目的。如果項目中不使用 GUI 功能: QT += multimedia multimediawidgets QT += sql

Qt控件的使用

QSpinBox、QDoubleSpinBox

QSpinBox常用于現在整數prefix為前綴,sufix為后綴

QDoubleSpinBox常用于顯示double,可以設置顯示的小數點位數,前后綴方式與QSpinbox相同

QTextEdit

QTextEdit的palatte可以用來顯示顏色,可做控制面板使用

QColor ?color; int R=ui->SliderRed->value(); ?//讀取SliderRed的當前值 int G=ui->SliderGreen->value();//讀取 SliderGreen 的當前值 int B=ui->SliderBlue->value();//讀取 SliderBlue 的當前值 int alpha=ui->SliderAlpha->value();//讀取 SliderAlpha 的當前值 color.setRgb(R,G,B,alpha); //使用QColor的setRgb()函數 獲得顏色 ? QPalette pal=ui->textEdit->palette();//獲取textEdit原有的 palette pal.setColor(QPalette::Base,color); //設置palette的基色(即背景色) ? ui->textEdit->setPalette(pal);//設置為textEdit的palette,改變textEdit的底色

進度條

QSlider為滑動條,值改變的槽函數為valuechanged(int)

QScollBar也為滑動條,類似網頁下面的滑動條,值改變的槽函數為valuechanged(int)

QProgressBa為進度條,可以顯示百分比及進度,類似軟件界面啟動加載界面,值改變的槽函數為valuechanged(int),但不可滑動類型QSlider和QScollBar改變他的值

QDial類似一個鐘表,滑動可以改變他的值,值改變的槽函數為valuechanged(int)

QLCDNumber

QLCDNumber常用于顯示數字和時間等,可以進行二進制、八進制、十進制、十六進制轉換顯示,也可以設置顯示的位數,通過display設置顯示的內容

ui->LCDDisaplay為ui界面的QLCDNumber控件

ui->LCDDisplay->display(value); //設置LCD顯示二進制數 ui->LCDDisplay->setDigitCount(8); ui->LCDDisplay->setBinMode(); //設置LCD顯示八進制數 ui->LCDDisplay->setDigitCount(4); ui->LCDDisplay->setOctMode(); //設置LCD顯示十六進制數 ui->LCDDisplay->setDigitCount(3); ui->LCDDisplay->setHexMode(); //設置LCD顯示十進制數 ui->LCDDisplay->setDigitCount(3); ui->LCDDisplay->setDecMode();

時間控件

QTimeEdit用于顯示當前時間的時分秒

QDateTime curDateTime=QDateTime::currentDateTime(); //讀取當前日期時間 ? //editTime為QlineEdit控件,使用字符轉換顯示時間 ui->timeEdit->setTime(curDateTime.time()); //設置時間 ui->editTime->setText(curDateTime.toString("hh:mm:ss"));//轉換為字符串顯示

QDateEdit用于顯示年月日

//editDate為QlineEdit控件,使用字符轉換顯示時間 ui->dateEdit->setDate(curDateTime.date());//設置日期 ui->editDate->setText(curDateTime.toString("yyyy-MM-dd"));//轉換為字符串顯示

QDateTimeedit用于顯示完整的時間年月日時分秒

//editDateTime為QlineEdit控件,使用字符轉換顯示時間 ui->dateTimeEdit->setDateTime(curDateTime);//設置日期時間 ui->editDateTime->setText(curDateTime.toString("yyyy-MM-dd hh:mm:ss"));//轉換為字符串顯示

QCalendarWidget為日歷控件,用于顯示日歷,槽函數為selectionChanged()函數,使用QDate可以獲取日歷上選擇的時間

void Dialog::on_calendarWidget_selectionChanged() { //在日歷上選擇日期QDate dt=ui->calendarWidget->selectedDate(); //讀取選擇的日期時間QString str=dt.toString("yyyy年M月d日");//轉換為字符串ui->editCalendar->setText(str); //字符串顯示日期 }

QPlainTextEdit

可以通過設置Qt界面的Property中的lineWrapMode屬性來設置是否自動換行,NoWrap為不自動換行

appendPlainText()為在QPlainTextEdit后面添加內容

QPlainTextEdit的文字內容以QTextDocument類型儲存,函數document返回這個文檔對象的指針。 QTextDocument是內存中的文本對象,以文本塊的方式儲存,每個段落以換行符結束 QTextDocument提供一些函數實現對文本內容的存取 int blockCount(),返回文本塊個數 QTextBlock finBlockByNumber(int ),讀取一個文本塊,序號從0開始

QTextDocument * doc = ui->plainTextEdit->document(); int count = doc->blockCount();QIcon ico(":/imasges/icons/aim.ico");for (int i = 0; i < count ; i++){ui->comboBox->addItem(ico, doc->findBlockByNumber(i).text());}

QComBox

?QIcon ico(":/imasges/icons/UNIT.ICO");QMap<QString, int> City_Zone;City_Zone.insert("北京",10);City_Zone.insert("上海",21);City_Zone.insert("天津",22);City_Zone.insert("大連",411);City_Zone.insert("錦州",416);City_Zone.insert("徐州",516);City_Zone.insert("福州",591);City_Zone.insert("青島",532); ?foreach(auto str, City_Zone.keys()){ui->comboBox2->addItem(ico, str, City_Zone.value(str));}通過foreach設置Qcombox的icon和值,addItem的第一個參數為icon,第二個參數為顯示的內容,第三個參數為value 槽事件 currentIndexChanged(const QSting & arg1);if(!arg1.isEmpty()){//獲取的是QComBox的第三個設置的值QString zone = ui->comboBox2->currentData().toString();ui->plainTextEdit->appendPlainText(arg1 + "區號" + zone);}槽事件中返回的參數為additem的第二個參數,currentData()為addItem中設置的第三個參數

QListWidget

通過QListWidgetItem來獲取QListWidget上的表項

QListWidgetItem * aItem = ui->listWidget->item(i); //通過setFlags來設置QListWidget上的表項的可用、可編輯、可選擇等 aItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEditable| Qt::ItemIsUserCheckable|Qt::ItemIsEnabled);

QListWidgetItem可在前面添加Icon

QListWidgetItem * aItem; QIcon icon(":/images/icons/check2.ico"); QString str = QString::asprintf("New Insert append"); aItem = new QListWidgetItem(str); aItem->setIcon(icon); aItem->setCheckState(Qt::Checked); ui->listWidget->addItem(aItem);

QActon可添加QMenu

QMenu * menu = new QMenu(this); menu->addAction(ui->actSelALL); menu->addAction(ui->actSelNone); menu->addAction(ui->actSelInvs); ui->actSelPopMenu->setMenu(menu);

QDockWidegt

QDockWidegt設置可見性和浮動性

void MainWindow::on_actDockVisible_triggered(bool arg1) {ui->dockWidget->setVisible(arg1); } ? void MainWindow::on_actDockFloat_triggered(bool checked) {ui->dockWidget->setFloating(checked); }

QDockWidegt自身具體槽事件,來監聽QDockWidegtd的可見性狀態和浮動性狀態topLevelChanged(bool topLevel)和visibilityChanged(bool visible)

void MainWindow::on_dockWidget_topLevelChanged(bool topLevel) {ui->actDockFloat->setChecked(topLevel); } ? void MainWindow::on_dockWidget_visibilityChanged(bool visible) {ui->actDockVisible->setChecked(visible); }

QTreeWidget

QTreeWidget通過QTreeWidgetItem來獲取QTreeWidget的某項數據,QTreeWidgetItem的數據分為兩部分

可以通過枚舉類型對QTreeWidget節點類型進行區分

//枚舉類型treeItemType, 用于創建 QTreeWidgetItem 時作為節點的type, 自定義類型必須大于1000 //itTopItem 頂層節點; itGroupItem 組節點; itImageItem 圖片 enum ?treeItemType{itTopItem=1001,itGroupItem,itImageItem}; //枚舉類型,表示列號 enum ?treeColNum{colItem=0, colItemType=1}; //目錄樹列的編號定義 QTreeWidgetItem * parItem = ui->treeWidget->currentItem(); QTreeWidgetItem * item = new QTreeWidgetItem(itGroupItem); QIcon icon(":/images/icons/open3.bmp"); item->setIcon(colItem, icon); item->setText(colItem, dir); item->setText(colItemType, "type:group"); item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate); //設置節點選項 item->setCheckState(colItem,Qt::Checked); //節點選中 ? //通過setData向QTreeWidgetItem里面設置數據 item->setData(colItem,Qt::UserRole,QVariant(fullname)); //設置角色為Qt::UserRole的Data,存儲完整目錄名稱 ? parItem->addChild(item); //在父節點下面添加子節點 //QTreeWidget的表項改變事件 void MainWindow::on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) {Q_UNUSED(previous);if(current==NULL) return;//獲取之前設置的枚舉類型int var = current->type();switch (var){case itTopItem:ui->actAddFiles->setEnabled(true);ui->actAddFolder->setEnabled(true);ui->actDeleteItem->setEnabled(true);break;case itGroupItem:ui->actAddFiles->setEnabled(true);ui->actAddFolder->setEnabled(true);ui->actDeleteItem->setEnabled(true);break;case itImageItem:ui->actAddFiles->setEnabled(true);ui->actAddFolder->setEnabled(false);ui->actDeleteItem->setEnabled(true);ui->actZoomIn->setEnabled(true);ui->actZoomFitH->setEnabled(true);ui->actZoomFitW->setEnabled(true);ui->actZoomOut->setEnabled(true);ui->actZoomRealSize->setEnabled(true);LabFileName.setText(current->data(colItem,Qt::UserRole).toString());//獲取QTreeWidgetItem之前設置的數據curPixmap.load(current->data(colItem,Qt::UserRole).toString());on_actZoomFitW_triggered();} }

QtableWidget

通過ui界面設置tabsCloseable設置QtableWidget是否具有關閉按鈕。

//將ui的center設置為Qtablewidget setCentralWidget(ui->tabWidget); ? //設置是否可見 ui->tabWidget->setVisible(false); ? //設置全屏顯示 //setWindowState(Qt::WindowMaximized);

Model、View結構

?數據:如數據庫的一個數據表或SQL查詢結果,內存中的一個 StringList,或磁盤文件結構等。

?Model:與數據通信,并為視圖組件提供數據接口。

?View:是屏幕上的界面組件,視圖從數據模型獲得每個數據項的模型索引(model index),通過模型索引獲取數據

?代理:定制數據的界面顯示和編輯方式。在標準的視圖組件中,代理功能顯示一個數據,當數據被編輯時,提供一個編輯器,一般是QLineEdit 。

模型、視圖和代理之間使用信號和槽通信

數據類型

Model用途
QStringListModel用于處理字符串列表數據的數據模型類
QStandardltemModel標準的基于項數據的數據模型類,每個項數據可以是任何數據類型
QFileSystemModel計算機上文件系統的數據模型類
QSortFilterProxyModel與其他數據模型結合,提供排序和過濾功能的數據模型類
QSqlQueryModel用于數據庫SQL查詢結果的數據模型類
QSqlTableModel用于數據庫的一個數據表的數據模型類
QSqlRelationalTableModel用于關系型數據表的數據模型類

數據模型中存儲數據的基本單元都是項(item),每個項有一個行號、一個列號,還有一個父項

QModelIndex 表示模型索引的類。模型索引提供數據存取的一個臨時指針

//Table Model QModelIndex indexA = model->index(0, 0, QModelIndex()); QModelIndex indexC = model->index(2, 1, QModelIndex()); //Tree Model indexA 表示indexB的根節點 QModelIndex indexB = model->index(1, 0, indexA);

QFileSystemModel

如同 Widnows 的資源管理器一樣。使用 QFileSystemModel 提供的接口函數,可以創建目錄、刪除目錄、重命名目錄,可以獲得文件名稱、目錄名稱、文件大小等參數,還可以獲得文件的詳細信息。

QFileSystemModel * model = new QFileSystemModel; model->setRootPath(QDir::currentPath());

//通過QFileSystemModel,使用QTreeView、QListView、QTableView可以直接通過QModleIndex調用QFileSystemModel讀取的內容

//給出this指針,當窗體關閉的時候,指針會自動進行回收 //直接給TreeView ListView tableView設置文件模型,即可顯示文件基本信息(類似文件管理器) fileMode = new QFileSystemModel(this); fileMode->setRootPath(QDir::currentPath()); ui->treeView->setModel(fileMode); ui->listView->setModel(fileMode); ui->tableView->setModel(fileMode); ui->tableView->verticalHeader()->setVisible(false); ? //連接信號,當QTreeViewd的表項發生變化時,QListView、QTableView發生相應的變化 connect(ui->treeView, SIGNAL(clicked(QModelIndex)), ui->listView, SLOT(setRootIndex(QModelIndex))); connect(ui->treeView, SIGNAL(clicked(QModelIndex)), ui->tableView, SLOT(setRootIndex(QModelIndex)));

可以通過QModelIndex來獲取QFileSystemModel存取的信息

void MainWindow::on_treeView_clicked(const QModelIndex &index) {//通過QFileSystemModel的QModelIndex來獲取文件名、文件大小、文件類型、及是否是文件夾ui->labName->setText(fileMode->fileName(index));ui->labPath->setText(fileMode->filePath(index));ui->labType->setText(fileMode->type(index));unsigned sz = fileMode->size(index) / 1024; ?if(sz < 1024){ui->labSize->setText(QString::asprintf("%d kb", sz));}else{ui->labSize->setText(QString::asprintf("%2F kb", (float)sz/1024));} ?ui->checkBox->setChecked(fileMode->isDir(index)); }

QStringListModel

//定義QStringListModel QStringListModel ?*themodel;

//設置QStringListModel 的數據

theModle = new QStringListModel(this); QStringList ? ? ? ? theStrList; //保存初始 StringList theStrList<<"北京"<<"上海"<<"天津"<<"河北"<<"山東"<<"四川"<<"重慶"<<"廣東"<<"河南"; //初始化 StringList theModle->setStringList(theStrList); //給QListView設置模式,即將QStringListModel的值給給QListView設置模式 ui->listView_2->setModel(theModle); //獲取QStringListModel設置的值QStringList strlist = theModle->stringList();//將從QStringListModel獲取的值設置到QPlainTextEdit中去foreach(auto str, strlist){ui->plainTextEdit_2->appendPlainText(str);}

QStandardItemModel

#define FixedColumnCount 6 QStandardItemModel ?*theModel;//數據模型 QItemSelectionModel *theSelection;//Item選擇模型 ? //為tableView設置數據模型 打通了Mode和View之間的關系 theModel = new QStandardItemModel(10, FixedColumnCount, this); theSelection = new QItemSelectionModel(theModel); ui->tableView->setModel(theModel); //設置數據模型 ui->tableView->setSelectionModel(theSelection);//設置選擇模型

QStandardItemModel添加數據

void MainWindow::iniModelFromStringList(QStringList& aFileContent) { //從一個StringList 獲取數據,初始化數據Modelint rowCnt=aFileContent.count(); //文本行數,第1行是標題theModel->setRowCount(rowCnt-1); //實際數據行數 ?//設置表頭QString header=aFileContent.at(0);//第1行是表頭//一個或多個空格、TAB等分隔符隔開的字符串, 分解為一個StringListQStringList headerList=header.split(QRegExp("\\s+"),QString::SkipEmptyParts);theModel->setHorizontalHeaderLabels(headerList); //設置表頭文字 ?//設置表格數據int j;QStandardItem ? *aItem;for (int i=1;i<rowCnt;i++){QString aLineText=aFileContent.at(i); //獲取 數據區 的一行//一個或多個空格、TAB等分隔符隔開的字符串, 分解為一個StringListQStringList tmpList=aLineText.split(QRegExp("\\s+"),QString::SkipEmptyParts);for (j=0;j<FixedColumnCount-1;j++) //tmpList的行數等于FixedColumnCount, 固定的{ //不包含最后一列aItem=new QStandardItem(tmpList.at(j));//創建itemtheModel->setItem(i-1,j,aItem); //為模型的某個行列位置設置Item} ?aItem=new QStandardItem(headerList.at(j));//最后一列是Checkable,需要設置aItem->setCheckable(true); //設置為Checkableif (tmpList.at(j)=="0")aItem->setCheckState(Qt::Unchecked); //根據數據設置check狀態elseaItem->setCheckState(Qt::Checked);theModel->setItem(i-1,j,aItem); //為模型的某個行列位置設置Item} } //設置QStandardItemModel表頭 QStringList ? ? headerList; headerList<<"Depth"<<"Measured Depth"<<"Direction"<<"Offset"<<"Quality"<<"Sampled"; theModel->setHorizontalHeaderLabels(headerList); //設置表頭文字 ? //設置QStandardItemModel行數 theModel->setColumnCount(5);

使用文件輸入輸出流讀寫文件

//打開文件 QString curPath=QCoreApplication::applicationDirPath(); //獲取應用程序的路徑 //調用打開文件對話框打開一個文件 QString aFileName=QFileDialog::getOpenFileName(this,"打開一個文件",curPath, "井數據文件(*.txt);;所有文件(*.*)"); if (aFileName.isEmpty()) return; //如果未選擇文件,退出 ? QStringList fFileContent;//文件內容字符串列表 QFile aFile(aFileName); ?//以文件方式讀出 if (aFile.open(QIODevice::ReadOnly | QIODevice::Text)) //以只讀文本方式打開文件 {QTextStream aStream(&aFile); //用文本流讀取文件ui->plainTextEdit->clear();//清空while (!aStream.atEnd()){QString str=aStream.readLine();//讀取文件的一行ui->plainTextEdit->appendPlainText(str); //添加到文本框顯示fFileContent.append(str); //添加到 StringList}aFile.close();//關閉文件 ?this->LabCurFile->setText("當前文件:"+aFileName);//狀態欄顯示ui->actAppend->setEnabled(true); //更新Actions的enable屬性ui->actInsert->setEnabled(true);ui->actDelete->setEnabled(true);ui->actSave->setEnabled(true); ?iniModelFromStringList(fFileContent);//從StringList的內容初始化數據模型 ?//設置行列自適應ui->tableView->resizeRowsToContents();ui->tableView->resizeColumnsToContents(); }

使用文件輸入輸出流保存文件

{ ? //打開文件QString curPath=QCoreApplication::applicationDirPath(); //獲取應用程序的路徑//調用打開文件對話框打開一個文件QString aFileName=QFileDialog::getSaveFileName(this,"選擇一個文件",curPath,"井數據文件(*.txt);;所有文件(*.*)");if (aFileName.isEmpty())return; //如果未選擇文件,退出 ?QFile aFile(aFileName); ?//以文件方式讀出if (!aFile.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) //以讀寫文本及覆蓋文本方式打開文件return; ?//以文件流對文件進行操作QTextStream stream(&aFile);QString str;ui->plainTextEdit->clear(); ?//獲取表頭數據QStandardItem * Item;for(int i = 0; i< theModel->columnCount(); i++){Item = theModel->horizontalHeaderItem(i);//加入兩個tab符,跟之前數據保持一致str = str + Item->text() + "\t\t";}//寫入數據stream << str << "\n";ui->plainTextEdit->appendPlainText(str); ?//獲取內容int j;//下表從0開始,因為上方已經將表頭元素分開for (int i = 0; i < theModel->rowCount(); i++){str = ""; ?for (j = 0; j < theModel->columnCount() - 1; j++){Item = theModel->item(i, j);str = str + Item->text()+ "\t\t";} ?//拿到最后一列Item = theModel->item(i, j);if(Item->checkState() == 1)str = str + "1";elsestr = str + "0"; ?//寫入數據stream << str << "\n";ui->plainTextEdit->appendPlainText(str); }

QItemSelectionModel

QItemSelectionModel常與QStandardItemModel連用

theModel = new QStandardItemModel(10, FixedColumnCount, this); theSelection = new QItemSelectionModel(theModel);

QItemSelectionModel主要用于獲取view中選擇的數據項位于model的那個位置及表格的位置

向QStandardItemModel里面插入數據

//使用Qlist對數據進行添加行 QList<QStandardItem *> itemList; ? QStandardItem * item; //往Model里面添加數據 for (int i = 0; i < FixedColumnCount - 1; i++) {item = new QStandardItem("000");itemList<<item; } //獲取表頭元素最后一列的數據 QString str = theModel->headerData(theModel->columnCount() -1, Qt::Horizontal,Qt::DisplayRole).toString(); ? //設置最后一行 item = new QStandardItem(str); item->setCheckState(Qt::Checked); itemList<<item; ? int curRow = theSelection->currentIndex().row(); //在Model最后一行添加數據 theModel->insertRow(curRow,itemList); ? //重新設置最后一行的選擇模式 theSelection->clearSelection(); QModelIndex index = theModel->index(curRow, 0); theSelection->setCurrentIndex(index,QItemSelectionModel::Select);

自定義代理

使用代理必須實現以下幾個函數:

?createEditor():創建用于編輯模型數據的widget組件,如QSpinBox,QComboBox。

?setEditorData():從數據模型獲取數據,供widget組件進行編輯 。

?setModelData():將widget上的數據更新到數據模型。

?updateEditorGeometry():用于給widget組件設置一個合適的大小。

QStyledItemDelegate為代理類,如果想要實現代理,需要繼承這個類,按f2進去可以了解要代理的部分,主要包括painting、editing、editor factory

將QlineEdit通過代理換成QSpinBox

//創建用于編輯模型數據的widget組件 QWidget *QIntDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {QSpinBox * editor = new QSpinBox(parent); ?//設置QSpinbox的屬性editor->setMinimum(0);editor->setMaximum(1000);editor->setFrame(false); ?return editor; } ? //從數據模型獲取數據,供widget組件進行編輯 void QIntDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const {//通過index獲取model 在通過model獲取數據int value = index.model()->data(index, Qt::EditRole).toInt(); ?//將類型轉換為QSpinbox類型QSpinBox * spinbox = static_cast<QSpinBox *>(editor); ?//設置值spinbox->setValue(value); } ? //將widget上的數據更新到數據模型 void QIntDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {//將類型轉換為QSpinbox類型QSpinBox * spinbox = static_cast<QSpinBox *>(editor); ?//拿到現在的取值spinbox->interpretText(); ?//設置modelint value = spinbox->value();model->setData(index, value, Qt::EditRole); } ? //用于給widget組件設置一個合適的大小 void QIntDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const {//設置大小editor->setGeometry(option.rect); }

寫好代理類之后通過在tableview(視圖)上設置即可使用

QIntDelegate intSpinDelegate;//設置自定義代理 //調用代理 //為第0列設置自定義代理 ui->tableView->setItemDelegateForColumn(0, &intSpinDelegate);

Qt對話框

標準對話框

QFileDialog

//選擇單個文件 QString curPath=QDir::currentPath();//獲取系統當前目錄 // QString curPath=QCoreApplication::applicationDirPath(); //獲取應用程序的路徑 QString dlgTitle="選擇一個文件"; //對話框標題 QString filter="文本文件(*.txt);;圖片文件(*.jpg *.gif *.png);;所有文件(*.*)"; //文件過濾器 ? QString aFileName=QFileDialog::getOpenFileName(this,dlgTitle,curPath,filter); ? if (!aFileName.isEmpty()) ui->plainTextEdit->appendPlainText(aFleName);

QColorDialog

//設置QplaintTextEdit字體顏色 QPalette pal = ui->plainTextEdit->palette(); QColor inicolor = pal.color(QPalette::Text); ? //通過QColorDialog選擇的顏色返回出來 inicolor為初始的顏色 QColor color = QColorDialog::getColor(inicolor, this, "選擇顏色"); ? //將獲取的樣式設置到QplainTextEdit中 if(!color.isValid()) return; pal.setColor(QPalette::Text, color); ui->plainTextEdit->setPalette(pal);

QFontDialog

//設置字體 bool ok = false; QFont iniFont = ui->plainTextEdit->font(); ? //第一個參數如果選擇成功 則返回true 否則返回false QFont font = QFontDialog::getFont(&ok, iniFont, this, "選擇字體"); ? //為QPliantTextEdit設置選擇的字體 if(!ok) return; ui->plainTextEdit->setFont(font);

輸入對話框

字符輸入對話框

//輸入字符串 QString dlgTitle="輸入文字對話框"; QString txtLabel="請輸入文件名"; QString defaultInput="新建文件.txt"; QLineEdit::EchoMode echoMode=QLineEdit::Normal;//正常文字輸入 // ? QLineEdit::EchoMode echoMode=QLineEdit::Password;//密碼輸入 ? bool ok=false; QString text = QInputDialog::getText(this, dlgTitle,txtLabel, echoMode,defaultInput, &ok);

整形輸入對話框

//輸入整數 QString dlgTitle="輸入整數對話框"; QString txtLabel="設置字體大小"; int defaultValue=ui->plainTextEdit->font().pointSize(); //現有字體大小 int minValue=6, maxValue=50,stepValue=1; //范圍,步長 bool ok=false; int inputValue = QInputDialog::getInt(this, dlgTitle,txtLabel, defaultValue, minValue,maxValue,stepValue,&ok); if (ok) //是否確認輸入 {QFont ? font=ui->plainTextEdit->font();font.setPointSize(inputValue);ui->plainTextEdit->setFont(font); }

浮點數輸入對話框

//輸入浮點數 QString dlgTitle="輸入浮點數對話框"; QString txtLabel="輸入一個浮點數"; float defaultValue=3.13; ? float minValue=0, maxValue=10000; ?//范圍 int decimals=2;//小數點位數 ? bool ok=false; float inputValue = QInputDialog::getDouble(this, dlgTitle,txtLabel, defaultValue, minValue,maxValue,decimals,&ok); if (ok) //確認選擇 {QString str=QString::asprintf("輸入了一個浮點數:%.2f",inputValue);ui->plainTextEdit->appendPlainText(str); }

條目輸入對話框

//條目選擇輸入 QStringList items; //ComboBox 列表的內容 items <<"優秀"<<"良好"<<"合格"<<"不合格"; ? QString dlgTitle="條目選擇對話框"; QString txtLabel="請選擇級別"; int ? ? curIndex=0; //初始選擇項 bool ? ?editable=true; //ComboBox是否可編輯 bool ? ?ok=false; QString text = QInputDialog::getItem(this, dlgTitle,txtLabel,items,curIndex,editable,&ok); ? if (ok && !text.isEmpty()) ui->plainTextEdit->appendPlainText(text);

標準消息框

Question消息框

QString dlgTitle="Question消息框"; QString strInfo="文件已被修改,是否保存修改?"; ? QMessageBox::StandardButton ?defaultBtn=QMessageBox::NoButton; //缺省按鈕 ? QMessageBox::StandardButton result;//返回選擇的按鈕 result=QMessageBox::question(this, dlgTitle, strInfo, QMessageBox::Yes|QMessageBox::No |QMessageBox::Cancel, defaultBtn); ? if (result==QMessageBox::Yes) ui->plainTextEdit->appendPlainText("Question消息框: Yes 被選擇"); else if(result==QMessageBox::No) ui->plainTextEdit->appendPlainText("Question消息框: No 被選擇"); else if(result==QMessageBox::Cancel) ui->plainTextEdit->appendPlainText("Question消息框: Cancel 被選擇"); else ui->plainTextEdit->appendPlainText("Question消息框: 無選擇");

information消息框

QString dlgTitle="information消息框"; QString strInfo="文件已經打開,字體大小已設置"; ? //QMessageBox::information(this, dlgTitle, strInfo);//使用缺省的按鈕 QMessageBox::information(this, dlgTitle, strInfo, QMessageBox::Ok,QMessageBox::NoButton);

warning消息框

QString dlgTitle="warning 消息框"; QString strInfo="文件內容已經被修改"; ? QMessageBox::warning(this, dlgTitle, strInfo);

critical消息框

QString dlgTitle="critical消息框"; QString strInfo="有不明程序訪問網絡"; QMessageBox::critical(this, dlgTitle, strInfo);

about消息框

QString dlgTitle="about消息框"; QString strInfo="我開發的數據查看軟件 V1.0 \n 保留所有版權"; ? QMessageBox::about(this, dlgTitle, strInfo);

自定義對話框及調用

如果想要在一個窗體調用使用另外一個窗體的元素,可以通過寫public方法,通過調用public方法實現調用,需要在被調用窗體發出信號供主窗體接收,如按確認按鈕發出accept()信號

首先在頭文件聲明方法

int ? ? rowCount();//獲取對話框輸入的行數 int ? ? columnCount();//獲取對話框輸入的列數 void ? ?setRowColumn(int row, int column); //初始對話框上兩個SpinBox的值

在cpp實現方法

int QWDialogSize::rowCount() { //用于主窗口調用獲得行數的輸入值return ?ui->spinBoxRow->value(); } ? int QWDialogSize::columnCount() {//用于主窗口調用獲得列數的輸入值return ?ui->spinBoxColumn->value(); } ? void QWDialogSize::setRowColumn(int row, int column) { //初始化數據顯示ui->spinBoxRow->setValue(row);ui->spinBoxColumn->setValue(column); }

在另外一個窗體添加頭文件,new出來然后調用

QWDialogSize ? ?*dlgTableSize=new QWDialogSize(this); //創建對話框dlgTableSize->setRowColumn(theModel->rowCount(),theModel->columnCount()); //對話框數據初始化 int ret=dlgTableSize->exec();// 以模態方式顯示對話框,用戶關閉對話框時返回 DialogCode值 if (ret==QDialog::Accepted) //OK鍵被按下,對話框關閉,若設置了setAttribute(Qt::WA_DeleteOnClose),對話框被釋放,無法獲得返回值 { //OK鍵被按下,獲取對話框上的輸入,設置行數和列數int cols=dlgTableSize->columnCount();theModel->setColumnCount(cols); ?int rows=dlgTableSize->rowCount();theModel->setRowCount(rows); } delete dlgTableSize; //刪除對話框 //如果不想刪除可以調用窗體的屬性,實現自動刪除 //dlgTableSize->setAttribute(Qt::WA_DeleteOnClose);

調用父窗體的方法

MainWindow *parWind = (MainWindow*)parentWidget(); //獲取主窗口 //首先在父窗體new出來 傳入this,作為父窗體 dlgLocate = new QWDialogLocate(this); //創建對話框,傳遞指針 dlgLocate->setAttribute(Qt::WA_DeleteOnClose); //對話框關閉時自動刪除對話框對象,用于不需要讀取返回值的對話框 ? //后調用父窗口的public方法 #include "mainwindow.h" void QWDialogLocate::on_btnSetText_clicked() {//定位到單元格,并設置字符串int row=ui->spinBoxRow->value(); //行號int col=ui->spinBoxColumn->value();//列號 ?MainWindow *parWind = (MainWindow*)parentWidget(); //獲取主窗口parWind->setACellText(row,col,ui->edtCaption->text()); //設置單元格文字if (ui->chkBoxRow->isChecked()) //行增ui->spinBoxRow->setValue(1+ui->spinBoxRow->value()); ?if (ui->chkBoxColumn->isChecked()) //列增ui->spinBoxColumn->setValue(1+ui->spinBoxColumn->value()); }

多窗體應用程序設計

//窗體的一些的屬性設置 void QWidget::setWindowState(Qt::WindowStates windowstate); 常量意義
Qt::NonModal無模態,不會阻止其他窗口的輸入
Qt::WindowModal窗口對于其父窗口、所有的上級父窗口都是模態的
Qt::ApplicationModal窗口對整個應用程序是模態的,阻止所有窗口的輸入
//設置窗體透明度 參數 level 是 1.0(完全不透明)至 0.0(完全透明)之間的數。窗口透明度缺省值是 1.0,即完全不透明。 void QWidget::setWindowOpacity(qreal level); //設置窗體屬性 void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on = true); 常量意義
Qt:: WA_AcceptDrops允許窗體接收拖放來的組件
Qt::WA_DeleteOnClose窗體關閉時刪除自己,釋放內存
Qt::WA_Hover鼠標進入或移出窗體時產生paint事件
Qt:: WAAcceptTouchEvents窗體是否接受觸屏事件

void QWidget::setWindowFlags(Qt::WindowFlags type); 表示窗體類型的常量
Qt::Widget這是 QWidget 類的缺省類型。這種類型的窗體,如果它有父窗體,就作為父窗 體的子窗體;否則就作為一個獨立的窗口
Qt::Window表明這個窗體是一個窗口,通常具有窗口的邊框、標題欄,而不管它是否有父窗體
Qt::Dialog表明這個窗體是一個窗口,并且要顯示為對話框(例如在標題欄沒有最小化、 最大化按鈕)。這是 QDialog 類的缺省類型
Qt::Popup表明這個窗體是用作彈出式菜單的窗體
Qt::Tool表明這個窗體是工具窗體,具有更小的標題欄和關閉按鈕,通常作為工具欄的 窗體
Qt::ToolTip表明這是用于 Tooltip 消息提示的窗體
Qt::SplashScreen表明窗體是splash屏幕,是 QSplashScreen 類的缺省類型
Qt::Desktop表明窗體是桌面,這是 QDesktopWidget 類的類型
Qt::SubWindow表明窗體是子窗體,例如 QMdiSubWindow 就是這種類型
控制窗體顯示效果的常量
Qt::MSWindowsFixedSizeDialogHint在 Windows 平臺上,使窗口具有更窄的邊框,用于固定大小的對話框
Qt::FramelessWindowHint創建無邊框窗口
WindowHint要定義窗體外觀定制窗體外觀的常量,需要先設置 Qt::Customize
Qt::CustomizeWindowHint關閉缺省的窗口標題欄
Qt::WindowTitleHint窗口有標題欄
Qt::WindowSystemMenuHint有窗口系統菜單
Qt::WindowMinimizeButtonHint有最小化按鈕
Qt::WindowMaximizeButtonHint有最大化按鈕
Qt::WindowMinMaxButtonsHint有最小化、最大化按鈕
Qt::WindowCloseButtonHint有關閉按鈕
Qt::Windo wContextHelpButtonHint有上下文幫助按鈕
Qt::WindowStaysOnTopHint窗口總是處于最上層
Qt::WindowStaysOnBottomHint窗口總是處于最下層
Qt::WindowTransparentForlnput窗口只作為輸出,不接受輸入

QMainWindow創建的時候可以使用其他窗體作為父窗體,如:

QMainWindow * testMain = new QMainWindow(this); testMain->setAttribute(Qt::WA_DeleteOnClose); testMain->setWindowTitle("多實例窗口,指定父窗口"); testMain->show();

但QWidget則一般不會使用QMainWindow作為它的父窗體,如果作為父窗體則貼在父窗體上不能移動,一般不傳入this指針使用

//不加入this窗體關閉不會進行自動回收 QFormDoc * fordoc = new QFormDoc(); //設置關閉時自動刪除 fordoc->setAttribute(Qt::WA_DeleteOnClose); //設置窗口標題 fordoc->setWindowTitle("基于QWidget的窗體,無父窗口,關閉時刪除"); //設置窗體透明度 fordoc->setWindowOpacity(0.7); fordoc->show();

MDI應用程序設計

MDI模式的使用應加入頭文件 #include "QMdiSubWindow"

//設置MDI模式 級聯展開為分為幾個不同窗體打開 平鋪展開為幾個窗體在同一個大窗體展開 void MainWindow::on_actViewMode_triggered(bool checked) {if(checked){//設置為TableView模式ui->mdiArea->setViewMode(QMdiArea::TabbedView); ?//設置tableview模式窗體可關閉ui->mdiArea->setTabsClosable(true); ?//設置平鋪展開和級聯展開不可用ui->actCascade->setEnabled(false);ui->actTile->setEnabled(false);}else{//設置為窗體模式(默認模式)ui->mdiArea->setViewMode(QMdiArea::SubWindowView); ?//設置平鋪展開和級聯展開可用ui->actCascade->setEnabled(true);ui->actTile->setEnabled(true);} } ? ? //這兩種模式在QMdiArea::SubWindowView(窗體模式)進行使用 void MainWindow::on_actCascade_triggered() {//設置QMdiArea級聯模式ui->mdiArea->cascadeSubWindows(); ? } ? void MainWindow::on_actTile_triggered() {//設置QMdiArea平鋪模式ui->mdiArea->tileSubWindows(); } ? //當當前選擇的Widget發生改變時,狀態欄顯示文件地址 void MainWindow::on_mdiArea_subWindowActivated(QMdiSubWindow *arg1) {//如果沒有窗口的話 設置剪切復制等為不可用 清空狀態欄的內容if(ui->mdiArea->subWindowList().count() == 0){ui->actCopy->setEnabled(false);ui->actCut->setEnabled(false);ui->actFont->setEnabled(false);ui->actPaste->setEnabled(false);ui->statusBar->clearMessage();}else{//顯示主窗口的文件名FormDoc * mdoc = (FormDoc *)ui->mdiArea->activeSubWindow()->widget();ui->statusBar->showMessage(mdoc->GetcurrentFileName());} } //打開文件 FormDoc為自定義QWidget void MainWindow::on_actDoc_Open_triggered() {bool needNew = false;FormDoc * mdoc; ?//獲取QMdiArea的個數if(ui->mdiArea->subWindowList().count() > 0){// ui->mdiArea->activeSubWindow()獲取的是QMdiSubWindow對象//如果想要獲取相應的Qwidget 需要使用ui->mdiArea->activeSubWindow()->widget();后進行類型轉換mdoc = (FormDoc*)ui->mdiArea->activeSubWindow()->widget();needNew = mdoc->isFileOpened();}else{needNew = true;} ?if(needNew){mdoc = new FormDoc(this);//向獲取QMdiArea里面添加Widgetui->mdiArea->addSubWindow(mdoc);} ?QString fileName = QFileDialog::getOpenFileName(this, "open", "", "C程序文件(.h *cpp);;所有文件" );mdoc->loadFromFile(fileName);mdoc->show();ui->actCopy->setEnabled(true);ui->actCut->setEnabled(true);ui->actFont->setEnabled(true);ui->actPaste->setEnabled(true); } //加載文件 使用QTextStream對文件進行讀取 void FormDoc::loadFromFile(QString &aFileName) {QFile file(aFileName); ?//QIODevice::ReadOnly設置為只讀 QIODevice::Text設置為文本格式,會自動處理\n \t等字符if(file.open(QIODevice::ReadOnly)|QIODevice::Text){//使用QTextStream對文本進行操作QTextStream stream(&file); ?//填充QPlainTextui->plainTextEdit->clear();ui->plainTextEdit->setPlainText(stream.readAll()); ?//獲取文件的路徑和名稱mCurrentFile = aFileName;QFileInfo fileinfo(aFileName);QString str = fileinfo.fileName();setWindowTitle(str); ?//設置為true,代表文檔已經是打開的狀態m_isOpen = true;} }

SPlash和登錄窗口

Qt有一個QSplashScreen類可以實現Splash窗口的功能,它提供了載入圖片,自動設置窗口無邊框效果等功能。

QSettings配置表的存入和讀取

#include <QSettings> //寫入注冊表 void DialogLogin::writeSettings() {//使用QSettings將信息寫入注冊表中 第一個參數為庫名 第二個參數為表名QSettings settings("LF-QT", "Simple6_5"); ?//為注冊表添加數據settings.setValue("Username", m_user);settings.setValue("PSWD", m_pswd);settings.setValue("saved", ui->chkBoxSave->isChecked());//是否保存 } ? //讀取配置表的數據 void DialogLogin::readSettings() {QSettings settings("LF-QT", "Simple6_5"); ?//獲取配置表數據 進行類型轉換//第一個參數為關鍵值 也就是SetValue的第一個參數,第二個參數為默認值bool saved = settings.value("saved", false).toBool();m_user = settings.value("Username", "user").toString(); ?//設置默認密碼 進行加密處理QString defaultPSWD = encrypt("123456");m_pswd = settings.value("PSWD", defaultPSWD).toString(); ?//如果勾選了 自動填充賬號if(saved){ui->editUser->setText(m_user);}ui->chkBoxSave->setChecked(saved); }

使用哈希算法對md5進行加密

#include <QCryptographicHash> //對密碼進行加密 QString DialogLogin::encrypt(const QString &str) {QByteArray btArray;btArray.append(str); ?//使用哈希算法進行加密 加密格式為md5類型QCryptographicHash hash(QCryptographicHash::Md5);hash.addData(btArray); ?//接收加密后的結果 并進行十六進制類型轉換存儲QByteArray resultArray = hash.result();QString resultmd5 = resultArray.toHex();return resultmd5; }

設置QDialog屬性

ui->editPSWD->setEchoMode(QLineEdit::Password); //密碼輸入編輯框設置為密碼輸入模式 this->setAttribute(Qt::WA_DeleteOnClose);//設置為關閉時刪除 this->setWindowFlags(Qt::SplashScreen); //設置為SplashScreen, 窗口無邊框,不在任務欄顯示

使用鼠標事件使得無標頭的QDialog可以進行移動

#include <QMouseEvent> ? //頭文件 protected://用于鼠標拖動窗口的鼠標事件操作void mousePressEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent *event);void mouseReleaseEvent(QMouseEvent *event);bool ? ?m_moving=false;//表示窗口是否在鼠標操作下移動QPoint ?m_lastPos; ?//上一次的鼠標位置 ? //cpp文件 void DialogLogin::mousePressEvent(QMouseEvent *event) {if(event->buttton == Qt::LeftButton){m_moving = true;//記錄移動的距離 globalPos()為鼠標點擊后的位置到(0,0)點距離 pos()為DialogLogin窗體到(0,0)點距離m_lastPos = event->globalPos() - pos();} ?return DialogLogin::mouseMoveEvent(event); } ? void DialogLogin::mouseMoveEvent(QMouseEvent *event) {if(m_moving && (event->buttton == Qt::LeftButton)){move(event->globalPos() - m_lastPos);m_lastPos = event->globalPos() - pos();} } ? void DialogLogin::mouseReleaseEvent(QMouseEvent *event) {m_moving = false; } ?

文本文件讀寫

枚舉值描述
QIODevice::ReadOnly以只讀方式打開
QIODevice::WriteOnly以只寫方式打開
QIODevice::ReadWrite以讀寫方式打開
QIODevice::Append新增加的內容將被追加到文件末尾
QIODevice::Truncate以重寫的方式打開,原有內容會被刪除
QIODevice::Text在讀取時,將行結束符轉換成 \n;在寫入時,將行結束符轉換成本地格式,例如 Win32 平臺上是 \r\n

QFile IODevice讀寫文件

#include <QFileDialog> //使用QFile讀取文件 void MainWindow::on_actOpen_IODevice_triggered() {//設置QFileDialog 屬性 獲得打開文件的文件路徑QString curPath = QCoreApplication::applicationDirPath();QString dlgTitle = "打開文件";QString filter = "程序(*.h *.cpp);;文本( *.txt);; 所有文件(*.*)";QString fileName = QFileDialog::getOpenFileName(this, curPath, dlgTitle, filter);if(fileName.isEmpty()) ?return; ?//使用QFile IODevice對文件進行讀取QFile file(fileName);if(file.open(QIODevice::ReadOnly | QIODevice::Text)){ui->plainTextEditIODevice->setPlainText(QString::fromLocal8Bit(file.readAll()));file.close();ui->tabWidget->setCurrentIndex(0);} } ? //使用QFile另存為文件 即寫文件 void MainWindow::on_actSave_IODevice_triggered() {//設置QFileDialog 屬性 獲得打開文件的文件路徑QString curPath = QCoreApplication::applicationDirPath();QString dlgTitle = "打開文件";QString filter = "程序(*.h);;文本( *.txt);; 所有文件(*.*)";QString fileName = QFileDialog::getSaveFileName(this, curPath, dlgTitle, filter);if(fileName.isEmpty()) ?return; ?//打開文件進行寫操作QFile file(fileName);if(file.open(QIODevice::WriteOnly | QIODevice::Text)){//獲取QPlainText的內容 并進行類型轉換后寫入文件內QString str = ui->plainTextEditIODevice->toPlainText(); ?//寫入文件QByteArray btyArray = str.toUtf8();file.write(btyArray, btyArray.length()); ?//關閉文件file.close(); ?//設置QtabWidget當前索引ui->tabWidget->setCurrentIndex(0);} }

QTextSteam讀寫文件

#include <QFileDialog> #include <QTextStream> //使用QTextStream進行讀取 void MainWindow::on_actOpen_TextStream_triggered() {//設置QFileDialog 屬性 獲得打開文件的文件路徑QString curPath = QCoreApplication::applicationDirPath();QString dlgTitle = "打開文件";QString filter = "程序(*.h *.cpp);;文本( *.txt);; 所有文件(*.*)";QString fileName = QFileDialog::getOpenFileName(this, curPath, dlgTitle, filter);if(fileName.isEmpty()) ?return; ?//使用QFile對文件進行讀取QFile file(fileName);if(file.open(QIODevice::ReadOnly | QIODevice::Text)){//QTextStream可以一行一行讀取QTextStream stream(&file); ?//設置自動識別編碼stream.setAutoDetectUnicode(true); ?//使用一行一行讀取while(stream.atEnd()){ui->plainTextEditTextSteam->appendPlainText(stream.readLine());}//ui->plainTextEditTextSteam->setPlainText(stream.readAll());file.close();ui->tabWidget->setCurrentIndex(1);} } ? //使用QTextSTream進行另存為操作 即寫操作 void MainWindow::on_actSave_TextStream_triggered() {//設置QFileDialog 屬性 獲得打開文件的文件路徑QString curPath = QCoreApplication::applicationDirPath();QString dlgTitle = "打開文件";QString filter = "程序(*.h);;文本( *.txt);; 所有文件(*.*)";QString fileName = QFileDialog::getSaveFileName(this, curPath, dlgTitle, filter);if(fileName.isEmpty()) ?return; ?//打開文件進行寫操作QFile file(fileName);if(file.open(QIODevice::WriteOnly | QIODevice::Text)){QTextStream stream(&file); ?//設置自動識別編碼stream.setAutoDetectUnicode(true); ?//獲取QPlainText的內容 并進行類型轉換后寫入文件內QString str = ui->plainTextEditTextSteam->toPlainText(); ?//使用文件流寫入文件stream<< str;file.close();ui->tabWidget->setCurrentIndex(1);} }

解決漢字亂碼問題

//解決漢字亂碼問題 一般寫在main函數內 其他文件讀寫操作都可解決亂碼問題 QTextCodec *codec = QTextCodec::codecForName("UTF-8"); QTextCodec::setCodecForLocale(codec); //解決漢字亂碼問題

二進制文件讀寫

二進制文件存儲方式

主要分為兩種,一種的大地址在前面,一種是小地址在前面。

0x1234567的存儲方式

1、小地址在前 2、大地址在前

0x100 0x101 0x102 0x013 0x100 0x101 0x102 0x013

01 23 45 67 67 45 23 01

使用 QFile 和 QDataStream 進行二進制數據文件的讀寫

QFile 負責文件的 IO 設備接口,即與文件的物理交互; QDataStream 以數據流的方式讀取文件內容或寫入文件內容。Qt預定義編碼 標準編碼

以 Qt 預定義編碼保存的 stm 文件的格式定義

順序號數據類型備注
1rowCountqintl6行數
2colCountqintl6列數
3“Depth”QString表頭標題1
4"Measured Depth"QString表頭標題2
5"Direction"QString表頭標題3
6"Offset"QString表頭標題4
7"Quality"QString表頭標題5
8"Sampled"QString表頭標題6
9第1行各列數據qint16測深
10qreal垂深
11qreal方位
12qreal位移
13QString固井質量
14bool是否測井取樣
15第2行各列數據

使用QDataStream 讀取二進制文件(.stm,.dat都是二進制文件),首先寫的時候要根據各種數據類型進行寫入,讀出的時候要根據寫入的時候的數據類型進行寫出,寫入的時候要注意,因為是根據二進制代碼進行寫入,一個出錯,其余都會跟著出錯。

使用QDataStream讀寫stm類型文件

使用QDataStream 寫.stm文件 stm文件需要設置版本好號

#include <QFileDialog> #include <QDataStream> //theModel為QStandardItemModel ? //使用QDataStream進行寫文件 需要根據流的方式進行寫入 void MainWindow::on_actSave_triggered() {//設置QFileDialog 屬性 獲得打開文件的文件路徑QString curPath = QCoreApplication::applicationDirPath();QString dlgTitle = "保存文件";QString filter = "Qt預編碼文件(*.stm)";QString fileName = QFileDialog::getSaveFileName(this, curPath, dlgTitle, filter);if(fileName.isEmpty()) ?return; ?//使用QFile IODevice對文件進行讀取QFile file(fileName); ?//QIODevice::Truncate對文件進行覆蓋if(file.open(QIODevice::WriteOnly | QIODevice::Truncate)){//使用QDataStream讀取二進制文件QDataStream stream(&file); ?//設置QDataStream的版本號 不設置默認會給一個版本號stream.setVersion(QDataStream::Qt_5_0); ?//存入表格行數和列數qint16 rowCount = theModel->rowCount();qint16 colCount = theModel->columnCount();stream<<rowCount;stream<<colCount; ?//存入表頭文字for(int i = 0; i < colCount; i++){stream<<theModel->horizontalHeaderItem(i)->text();} ?//數據區域qint16 Depth;qreal MeasuredDepth, Direction, Offset;QString Quality;bool Sampled; ?//從表格中獲取數據填入文件中for(int i = 0 ; i < rowCount; i++){Depth = theModel->item(i , 0)->data(Qt::DisplayRole).toInt();stream<<Depth; ?MeasuredDepth = theModel->item(i , 1)->data(Qt::DisplayRole).toFloat();stream<<MeasuredDepth; ?Direction = theModel->item(i , 2)->data(Qt::DisplayRole).toFloat();stream<<Direction; ?Offset = theModel->item(i , 3)->data(Qt::DisplayRole).toFloat();stream<<Offset; ?Quality = theModel->item(i , 4)->data(Qt::DisplayRole).toString();stream<<Quality; ?//最后一項為勾選框Sampled = (theModel->item(i , 5)->checkState() == Qt::Checked);stream<<Sampled;}file.close();} }

使用QDataSteam讀取二進制文件,需要按照寫入的格式進行讀取 讀取.stm文件

#include <QFileDialog> #include <QDataStream> //theModel為QStandardItemModel ? //打開二進制文件使用QStandardItemModel和QItemSelectionModel加載到Tabbleview中 void MainWindow::on_actOpen_triggered() {//設置QFileDialog 屬性 獲得打開文件的文件路徑QString curPath = QCoreApplication::applicationDirPath();QString dlgTitle = "打開文件";QString filter = "Qt預編碼文件(*.stm)";QString fileName = QFileDialog::getOpenFileName(this, curPath, dlgTitle, filter);if(fileName.isEmpty()) ?return; ?//使用QFile IODevice對文件進行讀取QFile file(fileName);if(file.open(QIODevice::ReadOnly)){//使用QDataStream讀取二進制文件QDataStream stream(&file); ?//設置QDataStream的版本號 不設置默認會給一個版本號stream.setVersion(QDataStream::Qt_5_0);//數據區域qint16 rowCount, colCount;stream>>rowCount;stream>>colCount;resetTableRow(rowCount); ?//將不需要的數據輸出給strQString str;for(int i = 0; i < colCount; i++){stream>>str;} ?//數據區域qint16 Depth;qreal MeasuredDepth, Direction, Offset;QString Quality;bool Sampled; ?//根據index獲取Item,使用item填充數據 一共有六行數據QStandardItem * item;QModelIndex index;for(int i = 0; i < rowCount; i++){stream>>Depth;index = theModel->index(i, 0);item = theModel->itemFromIndex(index);item->setData(Depth, Qt::DisplayRole); ?stream>>MeasuredDepth;index = theModel->index(i, 1);item = theModel->itemFromIndex(index);item->setData(MeasuredDepth, Qt::DisplayRole); ?stream>>Direction;index = theModel->index(i, 2);item = theModel->itemFromIndex(index);item->setData(Direction, Qt::DisplayRole); ?stream>>Offset;index = theModel->index(i, 3);item = theModel->itemFromIndex(index);item->setData(Offset, Qt::DisplayRole); ?stream>>Quality;index = theModel->index(i, 4);item = theModel->itemFromIndex(index);item->setData(Quality, Qt::DisplayRole); ?stream>>Sampled;index = theModel->index(i, 5);item = theModel->itemFromIndex(index);//設置選中狀態if(Sampled)item->setCheckState(Qt::Checked);elseitem->setCheckState(Qt::Unchecked);}file.close();} }

使用QDataStream讀寫dat類型文件

寫dat文件 dat為標準編碼,可以不設置版本號 但是需要設置編碼格式

void MainWindow::on_actSaveBin_triggered() {//設置QFileDialog 屬性 獲得打開文件的文件路徑QString curPath = QCoreApplication::applicationDirPath();QString dlgTitle = "保存文件";QString filter = "Qt預編碼文件(*.dat)";QString fileName = QFileDialog::getSaveFileName(this, curPath, dlgTitle, filter);if(fileName.isEmpty()) ?return; ?//使用QFile IODevice對文件進行讀取QFile file(fileName); ?//QIODevice::Truncate對文件進行覆蓋if(file.open(QIODevice::WriteOnly | QIODevice::Truncate)){//使用QDataStream讀取二進制文件QDataStream stream(&file); ?//設置編碼規則 分為兩種stream.setByteOrder(QDataStream::LittleEndian); ?//存入表格行數和列數qint16 rowCount = theModel->rowCount();qint16 colCount = theModel->columnCount(); ?//寫的時候 整形浮點型使用writeRawData() 該方法是根據地址和大小寫入stream.writeRawData((char *) &rowCount, sizeof(qint16));stream.writeRawData((char *) &colCount, sizeof(qint16)); ? ?//存入表頭文字 QString型的寫入使用writeBytes()QByteArray btArray;for(int i = 0; i < colCount; i++){QString str = theModel->horizontalHeaderItem(i)->text();btArray = str.toUtf8();stream.writeBytes(btArray, btArray.length());} ?//數據區域qint16 Depth;qreal MeasuredDepth, Direction, Offset;QString Quality;bool Sampled; ?//從表格中獲取數據填入文件中for(int i = 0 ; i < rowCount; i++){Depth = theModel->item(i , 0)->data(Qt::DisplayRole).toInt();stream.writeRawData((char *) &Depth, sizeof(qint16)); ?MeasuredDepth = theModel->item(i , 1)->data(Qt::DisplayRole).toFloat();stream.writeRawData((char *) &MeasuredDepth, sizeof(qreal)); ?Direction = theModel->item(i , 2)->data(Qt::DisplayRole).toFloat();stream.writeRawData((char *) &Direction, sizeof(qreal)); ?Offset = theModel->item(i , 3)->data(Qt::DisplayRole).toFloat();stream.writeRawData((char *) &Offset, sizeof(qreal)); ?Quality = theModel->item(i , 4)->data(Qt::DisplayRole).toString();btArray = Quality.toUtf8();stream.writeBytes(btArray, btArray.length()); ?//最后一項為勾選框Sampled = (theModel->item(i , 5)->checkState() == Qt::Checked);qint8 yes = 1, no = 0;if(Sampled){stream.writeRawData((char *) &yes, sizeof(qint8));}else{stream.writeRawData((char *) &no, sizeof(qint8));}}} }

使用DataStream讀取.dat文件

//打開.dat文件 void MainWindow::on_actOpenBin_triggered() {//設置QFileDialog 屬性 獲得打開文件的文件路徑QString curPath = QCoreApplication::applicationDirPath();QString dlgTitle = "打開文件";QString filter = "標準編碼(*.dat)";QString fileName = QFileDialog::getOpenFileName(this, curPath, dlgTitle, filter);if(fileName.isEmpty()) ?return; ?//使用QFile IODevice對文件進行讀取QFile file(fileName);if(file.open(QIODevice::ReadOnly)){//使用QDataStream讀取二進制文件QDataStream stream(&file); ?//設置編碼規則 分為兩種stream.setByteOrder(QDataStream::LittleEndian); ?qint16 rowCount,colCount; ?//根據數據類型的大小進行讀取數據 int類型使用readRawData進行讀取stream.readRawData((char *) &rowCount, sizeof(qint16));stream.readRawData((char *) &colCount, sizeof(qint16)); ?//初始化表格resetTableRow(rowCount); ?//使用readBytes讀取QString數據char * buf;uint strlen; ?//也就是 quint32for(int i = 0; i < colCount; i++){stream.readBytes(buf, strlen); ?//根據buf獲取相應的字符串數據 改例子不需要使用//QString str = QString::fromLocal8Bit(buf, strlen);} ?//數據區域qint16 Depth;qreal MeasuredDepth, Direction, Offset;QString Quality; ?//使用readRawData時不支持bool類型,因此使用qint8較小的一個類型qint8 Sampled; ?//根據index獲取Item,使用item填充數據 一共有六行數據QStandardItem * item;QModelIndex index;for(int i = 0; i < rowCount; i++){stream.readRawData((char *) &Depth, sizeof(qint16));index = theModel->index(i, 0);item = theModel->itemFromIndex(index);item->setData(Depth, Qt::DisplayRole); ?stream.readRawData((char *) &MeasuredDepth, sizeof(qreal));index = theModel->index(i, 1);item = theModel->itemFromIndex(index);item->setData(MeasuredDepth, Qt::DisplayRole); ?stream.readRawData((char *) &Direction, sizeof(qreal));index = theModel->index(i, 2);item = theModel->itemFromIndex(index);item->setData(Direction, Qt::DisplayRole); ?stream.readRawData((char *) &Offset, sizeof(qreal));index = theModel->index(i, 3);item = theModel->itemFromIndex(index);item->setData(Offset, Qt::DisplayRole); ?stream.readBytes(buf, strlen);QString Quality = QString::fromLocal8Bit(buf, strlen);index = theModel->index(i, 4);item = theModel->itemFromIndex(index);item->setData(Quality, Qt::DisplayRole); ?stream.readRawData((char *) &Offset, sizeof(qint8));index = theModel->index(i, 5);item = theModel->itemFromIndex(index);//設置選中狀態if(Sampled == 1)item->setCheckState(Qt::Checked);elseitem->setCheckState(Qt::Unchecked);}file.close();} }

文件目錄操作

文件操作相關的類

QCoreApplication:用于提取應用程序路徑、程序名等文件信息 QFile:除了打開文件操作外,還有復制文件、刪除文件等功能 QFileInfo:用于提取文件信息,包括路徑、文件名、后綴 QDir:用于提取目錄或文件信息,獲取一個目錄下的文件或目錄列表,創建或刪除目錄和文件,文件重名等操作 QTemporaryDir 和 QTemporaryFile:用于創建臨時目錄和臨時文件。 QFileSystemWatcher:監聽目錄下文件的添加、刪除等變化

通過object對象獲取QPushbutton對象

//第一種寫法 void MainWindow::on_pushButton_68_clicked() {//通過sender()的object對象獲取QPushbutton對象 即可通過指針btn對點擊的按鈕進行操作QPushButton * btn = static_cast<QPushButton *>(sender()); ?//將QPushbutton的文本和提示內容添加到QPlainTextEdit中去ui->plainTextEdit_3->appendPlainText(btn->text());ui->plainTextEdit_3->appendPlainText(btn->toolTip()); } ? void MainWindow::on_pushButton_68_clicked() {GetBtnInfo(sender());//獲取當前的目錄添加到QPlainTextEdit中去ui->plainTextEdit_3->appendPlainText(QCoreApplication::applicationDirPath()); } ? //第二種寫法 //獲取點擊按鈕的文本和提示信息 void MainWindow::GetBtnInfo(QObject * obj) {QPushButton * btn = static_cast<QPushButton *>(obj); ?//將QPushbutton的文本和提示內容添加到QPlainTextEdit中去ui->plainTextEdit_3->appendPlainText(btn->text());ui->plainTextEdit_3->appendPlainText(btn->toolTip()); } QCoreApplication常用方法 applicationFilePath() : QString applicationName() : QString ? QFile常用方法 qint64 QFile::size() const //獲取當前文件的大小。對于打開的文件,該方法返回文件中可以讀取的字節數。 bool QIODevice::getChar(char *c) //從文件中讀取一個字符,并存儲到 c 中。讀取成功時,方法返回 true,否則返回 false。 bool QIODevice::putChar(char c) ? ?//向文件中寫入字符 c,成功時返回 true,否則返回 false。 QByteArray QIODevice::read(qint64 maxSize) //從文件中一次性最多讀取 maxSize 個字節,然后返回讀取到的字節。 qint64 QIODevice::read(char *data, qint64 maxSize) //從文件中一次性對多讀取 maxSize 個字節,讀取到的字節存儲到data指針指定的內存控件中。該方法返回成功讀取到的字節數。 QByteArray QIODevice::readAll() //讀取文件中所有的數據。 qint64 QIODevice::readLine(char *data, qint64 maxSize) //每次從文件中讀取一行數據或者讀取最多 maxSize-1 個字節,存儲到 data 中。該方法返回實際讀取到的字節數。 qint64 QIODevice::write(const char *data, qint64 maxSize) //向 data 數據一次性最多寫入 maxSize 個字節,該方法返回實際寫入的字節數。 qint64 QIODevice::write(const char *data) //將 data 數據寫入文件,該方法返回實際寫入的字節數。 qint64 QIODevice::write(const QByteArray &byteArray) //將 byteArray 數組中存儲的字節寫入文件,返回實際寫入的字節數。 bool QFile::copy(const QString &newName) //將當前文件的內容拷貝到名為 newName 的文件中,如果成功,方法返回 true,否則返回 false。copy 方法在執行復制操作之前,會關閉源文件。 bool QFile::rename(const QString &newName) //對當前文件進行重命名,新名稱為 newName,成功返回 true,失敗返回 false。 bool QFile::remove() //刪除當前文件,成功返回 true,失敗返回 false。QFileInfo常用方法 ? 一般用法: QFilelnfo filelnfo(path); QFilelnfo filelnfo;filelnfo.setFile(path); bool exists(); //判斷文件是否存在,若存在返回true。 qint64 size();//獲取文件大小,返回bytes。 QString path();//返回文件路徑,不包含文件名。 QString filePath();//返回文件路徑,包含文件名。 QString fileName();//返回文件名稱。 bool isFile();//判斷是否是文件。 bool isDir();//判斷是否是路徑。 bool isSymLink();//判斷是否是符號鏈接 QDateTime created();//創建時間 QDateTime lastModified();//最近修改時間 QDateTime lastRead();//最近讀時間 ? QDird的常用使用方法 mkdir();//創建一個目錄; rename();//對關聯目錄進行重命名; rmdir();//移除一個目錄; exists();//檢測目錄是否存在; refresh();//刷新目錄內容。 ? QTemporaryDir方法 QString errorString() const 如果isValid()返回false,則此函數返回錯誤字符串,該錯誤字符串解釋了為什么創建臨時目錄失敗。否則,這個函數返回一個空字符串。 QString filePath(const QString &fileName) const 返回臨時目錄中文件的路徑名稱。不檢查文件是否確實存在于目錄中。冗余多重分隔符或“。” 和fileName中的“..”目錄不會被刪除。 bool isValid() const 判斷生成的臨時目錄是否有效。 QString path() const 返回臨時目錄的路徑。如果無法創建QTemporaryDir,則為空。 bool remove() 刪除臨時目錄,包括其所有內容,并返回刪除狀態。 void setAutoRemove(bool b) 如果b為真,則將QTemporaryDir設置為自動刪除模式。 ? QTemporaryFile方法 void QTemporaryFile::setFileTemplate(const QString&name) 將文件名稱的靜態部分設置為名稱。如果文件模板包含將自動替換為文件名的唯一部分的XXXXXX,否則文件名將根據指定的靜態部分自動確定。 如果name包含相對文件路徑,則路徑將相對于當前工作目錄。如果你想使用系統的臨時目錄,你可以使用QDir :: tempPath()來構造名字。 bool open() 一個QTemporaryFile將永遠被打開了QIODevice::ReadWrite 模式,這可以方便地訪問文件中的數據。該函數在成功時將返回true,并將fileName()設置為使用的唯一文件名。QFileSystemWatcher方法bool addPath(const QString & path) 如果路徑存在,則添加至文件系統監控,如果路徑不存在或者已經被監控了,那么不添加。如果路徑是一個目錄,內容被修改或刪除時,會發射directoryChanged()信號;否則,當文件被修改、重命名或從磁盤上刪除時,會發出fileChanged()信號。如果監控成功,返回true;否則,返回false.監控失敗的原因通常依賴于系統,但也包括資源不存在、接入失敗、或總的監控數量限制等原因。 QStringList addPaths(const QStringList & paths) 添加每一個路徑至添加至文件系統監控,如果路徑不存在或者已經被監控了,那么不添加。返回值是不能被監控的路徑列表。 QStringList directories() const 返回一個被監控的目錄路徑列表。 QStringList files() const 返回一個被監控的文件路徑列表。 bool removePath(const QString & path) 從文件系統監控中刪除指定的路徑。如果監控被成功移除,返回true。刪除失敗的原因通常是與系統相關,但可能是由于路徑已經被刪除。 QStringList removePaths(const QStringList & paths) 從文件系統監控中刪除指定的路徑。返回值是一個無法刪除成功的路徑列表。

QPainter基本繪制

Qt可以使用相同的 API 在屏幕和繪圖設備上進行繪制,它主要基于QPainter、QPaintDevice 和 QPaintEngine 這三個類。 QPainter:用來進行繪圖操作的類 QPaintDevice:抽象的二維界面,是中間媒介 QPaintEngine:提供了一些接口,可用于 QPainter 在不同的設備上進行繪制

QPainter 可以在繼承自 QPaintDevice 類的任何對象上進行繪制操作

QPainter 一般在部件的繪圖事件 paintEvent() 中進行繪制。當窗口程序需要升級或者重新繪制時,調用此成員函數。使用 repaint()和 update() 后,調用函數 paintEvent()。

QPainter的3個主要設置是: pen, brush, fontpainter.setPen(QPen(..));painter.setBruch(QBrush(..));painter.setFont(QFont(..));painter.setRenderHint(QPainter::Antialiasing);設置了bursh之后, 畫的是效果即填充QPainter的屬性影響繪制的圖形 通常使用painter.drawXXX(..)來繪制圖形

//設置派生類 Q_DECL_OVERRIDE表示父類一定要存在 否則會提示報錯 void paintEvent(QPaintEvent * event) Q_DECL_OVERRIDE; #include<QPainter> void Widget::paintEvent(QPaintEvent * event) {QPainter painter(this); ?//獲取窗體的長和寬int w = this->width();int h = this->height(); ?//設置點抗鋸齒和文字抗鋸齒 // ? painter.setRenderHint(QPainter::Antialiasing); // ? painter.setRenderHint(QPainter::TextAntialiasing); ?QPen pen; ?//設置畫筆的寬度pen.setWidth(20); ?//設置畫筆的顏色pen.setColor(Qt::red); ?//設置線的類型 設置為圓和虛線形pen.setStyle(Qt::DashDotDotLine); ?//設置接口出處類型 設置為圓角類型pen.setJoinStyle(Qt::RoundJoin); ?//為畫家設置畫筆painter.setPen(pen); ?//設置填充顏色和類型QBrush brush;brush.setColor(Qt::yellow);brush.setStyle(Qt::Dense1Pattern);painter.setBrush(brush);設置線性漸變 // ? QLinearGradient linearGrad(rect.left(),rect.top(),rect.right(),rect.bottom()); //對角線 // ? QLinearGradient linearGrad(rect.left(),rect.top(),rect.right(),rect.top());//從左到右 // ? linearGrad.setColorAt(0,Qt::blue);//起點顏色 // ? linearGrad.setColorAt(0.5,Qt::green);//起點顏色 // ? linearGrad.setColorAt(1,Qt::red);//終點顏色 // ? linearGrad.setSpread(QGradient::ReflectSpread); //展布模式 QGradient::PadSpread ,QGradient::RepeatSpread, QGradient::ReflectSpread // ? painter.setBrush(linearGrad););// ? //畫矩形 // ? QRect rect(w/4, h/4, w/2, h/2); // ? painter.drawRect(rect);// ? //畫圖片和文字 // ? QRect rect(w/4, h/4, w/2, h/2); // ? QImage image(":images/images/qt.jpg"); // ? painter.drawImage(rect, image); // ? QFont font; // ? font.setPointSize(30); // ? painter.setFont(font); // ? painter.drawText(rect, "Hello Qt"); ?//繪制多邊形QPoint points[] = {QPoint(w/3, h/3), QPoint(w/2, h/2), QPoint(w/5, 2 * h/5)};painter.drawPolyline(points, 3); }

坐標系統和坐標轉換

對坐標進行平移和旋轉,實際上是對原始坐標系統進行平移旋轉,即改變了原點(0,0)位置和方向

分組函數原型功能
坐標變換void translate(qreal dx,qreal dy) void rotate(qreal angle) void scale(qreal sx,qreal sy) void shear(qrael sh,qreal sy)坐標系統一定的偏移量,坐標原點平移到新的點 坐標系統順時針旋轉一個角度 坐標系統縮放 坐標系統做扭轉變換
狀態保存與恢復void save() void restore() void resetTransform()保存painter當前的狀態,就是將當前狀態壓入棧 恢復上一次狀態,就是從堆棧中彈出上次的狀態 復位所有的坐標變換
void Widget::paintEvent(QPaintEvent * event) {Q_UNUSED(event); ?//設置畫筆的樣式 創建時一定要傳入this對象QPainter painter(this);QPen pen;pen.setStyle(Qt::SolidLine);painter.setPen(pen); ?//設置抗鋸齒painter.setRenderHint(QPainter::Antialiasing); ?//設置填充的樣式和顏色QBrush brush;brush.setColor(Qt::yellow);brush.setStyle(Qt::SolidPattern);painter.setBrush(brush); ?//畫五角星 設五角星的中心為中點 中點到頂點的距離為Rqreal R = 100; ?//將每個角度的長度轉換為弧度qreal deg = PI * (360 / 5) / 180;QPoint points[5] ={QPoint(R,0),QPoint(R*qCos(deg), -R*qSin(deg)),QPoint(R*qCos(2*deg), -R*qSin(2*deg)),QPoint(R*qCos(3*deg), -R*qSin(3*deg)),QPoint(R*qCos(4*deg), -R*qSin(4*deg))}; ?//根據點的路徑畫線段QPainterPath starPath;starPath.moveTo(points[0]);starPath.lineTo(points[2]);starPath.lineTo(points[4]);starPath.lineTo(points[1]);starPath.lineTo(points[3]);starPath.closeSubpath(); //閉合路徑,最后一個點與第一個點相連 ?//設置字體QFont ? font;font.setPointSize(12);font.setBold(true);painter.setFont(font); ?//在路徑上添加文字starPath.addText(points[0],font,"0"); //顯示端點編號starPath.addText(points[1],font,"1");starPath.addText(points[2],font,"2");starPath.addText(points[3],font,"3");starPath.addText(points[4],font,"4"); ?//保存坐標狀態painter.save(); ?//移動原點坐標painter.translate(100, 120); ?//畫線段painter.drawPath(starPath); ?//在中心畫文字,因為進行了平移,所以中心點大概在平移后的0,0位置painter.drawText(0, 0, "s1"); ?//恢復到保存時的坐標狀態 畫旋轉后的五角星painter.restore();painter.translate(300, 120);painter.rotate(90); ? ? ? ? //設置旋轉角度painter.scale(0.7, 0.7); ? ?//縮小painter.drawPath(starPath);painter.drawText(0, 0, "s2"); ? ?//恢復到最初的狀態painter.resetTransform();painter.translate(500, 120);painter.rotate(-90); ? ? ? ? //設置旋轉角度painter.scale(1.1, 0.7); ? ?//長度擴大 寬度縮小painter.drawPath(starPath);painter.drawText(0, 0, "s2"); }

視口坐標和窗口坐標

視口: 繪圖設備的任意一個矩形區域的物理坐標,可以只選取物理坐標的一個矩形區域用于繪圖。視口默認情況下等于繪圖設備的整個矩形區。 窗口: 對應于視口的矩形區域,只不過是用邏輯坐標定義的坐標系,窗口坐標的中心在矩形中心。

void Widget::paintEvent(QPaintEvent * event) {Q_UNUSED(event);QPainter painter(this);int w = this->width();int h = this->height(); ?//設置抗鋸齒painter.setRenderHint(QPainter::Antialiasing); ?//設置視口的大小 根據窗口的最小長度設置矩形框int side = qMin(w, h);QRect rect( (w - side) / 2, (h - side) / 2, side, side);painter.drawRect(rect); ?//設置視口坐標painter.setViewport(rect); ?//畫橢圓 設置窗口坐標 左上角坐標為-100,100 中心點為0,0 長度為200,寬度為200painter.setWindow(-100, -100, 200, 200); ? // ? //相當于在0,0點畫了一個矩形 再到矩形框內畫橢圓 // ? painter.drawEllipse(0, 0, 50, 50); ?//設置顏色漸變效果 前兩個參數為漸變的起始點 后兩個坐標為漸變的終止點QLinearGradient linearGrad(0, 0, 100, 0); ?//設置起始點顏色和終止點顏色 0為起點 1為終點linearGrad.setColorAt(0, Qt::yellow);linearGrad.setColorAt(1, Qt::green); ?//設置發散的形式 為按邊界顏色發散linearGrad.setSpread(QGradient::PadSpread);painter.setBrush(linearGrad); ?//設置復合模式painter.setCompositionMode(QPainter::CompositionMode_Difference); ?//根據旋轉畫圖案for (int i = 0; i < 36; i++){//旋轉painter.rotate(10); ?//設置橢圓的中心點 使用窗口坐標繪制 50相當于是半徑painter.drawEllipse(QPoint(50,0), 50, 50);} }

QtCharts

Qt Charts概述

Qt Charts基于Qt的Graphics View架構,其核心組件是QChartView和QChart ? QChartView是顯示圖標的視圖,基類為QGraphicsView ? QChart的基類是QGraphicsItem

要在項目中使用 Qt Charts 模塊,必須在項目的配置文件 . pro 文件中增加下面的一行語句 : QT += charts 在需要使用 QtCharts 的類的頭文件或源程序文件中 , 要使用如下的包含語句 : #include <QtCharts> //using namespace QtCharts ; QT_CHARTS_USE_NAMESPACE //使用宏定義

//,pro中加charts QT += charts ? #include "mainwindow.h" #include "ui_mainwindow.h" #include <QChartView> #include <QLineSeries> #include <QtMath> #include <QValueAxis> ? //加入宏定義 或者就要加入命名空間 using namespace QtCharts ; QT_CHARTS_USE_NAMESPACE ? MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);QChartView * chartView = new QChartView(this);QChart * chart = new QChart;chart->setTitle("簡單函數曲線"); ?//給chartview設置chart并鋪滿整個窗體chartView->setChart(chart);this->setCentralWidget(chartView); ?//創建折線序列QLineSeries * series0 = new QLineSeries;QLineSeries * series1 = new QLineSeries;series0->setName("sin曲線");series1->setName("cos曲線"); ?//為表格添加曲線chart->addSeries(series0);chart->addSeries(series1); ?//為序列添加數值qreal t=0,y1,y2,intv=0.1;int cnt=100;for(int i=0;i<cnt;i++){y1=qSin(t);//+qrand();series0->append(t,y1);y2=qCos(t);series1->append(t,y2);t+=intv;} ?//創建坐標軸QValueAxis * axisX =new QValueAxis;QValueAxis * axisY = new QValueAxis; ?//設置x軸axisX->setRange(0, 10);chart->setAxisX(axisX, series0);chart->setAxisX(axisX, series1); ?//設置Y軸axisY->setRange(-1, 1);chart->setAxisY(axisY, series0);chart->setAxisY(axisY, series1); }

Qtchart繪制折線圖

對QChart的進行方法縮小

//chartview為QChartView控件 chart為Qhart控件 chartview->setchart(chart); //縮小表格 void MainWindow::on_actZoomOut_triggered() {ui->chartview->chart()->zoom(0.8); } //放大表格 void MainWindow::on_actZoomIn_triggered() {ui->chartview->chart()->zoom(1.2); } //恢復原始大小 void MainWindow::on_actZoomReset_triggered() {ui->chartview->chart()->zoomReset(); }

創建圖表

//頭文件 #include <QtCharts> #include <QValueAxis> QT_CHARTS_USE_NAMESPACE private:Ui::MainWindow *ui;QLineSeries * curSeries;QValueAxis * curAxis; ? //創建圖表 void MainWindow::createChart() {QChart * chart = new QChart();chart->setTitle("簡單的曲線");ui->chartview->setChart(chart); ?//設置抗鋸齒模式ui->chartview->setRenderHint(QPainter::Antialiasing); ?QLineSeries * series0 = new QLineSeries;QLineSeries * series1 = new QLineSeries;series0->setName("sin曲線");series1->setName("cos曲線");curSeries = series0; ?//設置筆的樣式QPen pen;pen.setStyle(Qt::DotLine);pen.setWidth(2);pen.setColor(Qt::red);series0->setPen(pen);pen.setStyle(Qt::SolidLine);pen.setColor(Qt::blue);series1->setPen(pen); ?//為Chart添加序列chart->addSeries(series0);chart->addSeries(series1); ?//設置坐標軸QValueAxis * axisX = new QValueAxis;QValueAxis * axisY = new QValueAxis;curAxis = axisX; ?//設置坐標軸屬性axisX->setRange(0, 10);axisX->setTitleText("time(secs)"); ?//設置坐標軸為一位小數axisX->setLabelFormat("%.1f"); ?//設置中間格子一共多少條線axisX->setTickCount(11); ?//設置小分格axisX->setMinorTickCount(4); ?axisY->setRange(-1.5, 1.5);axisY->setTickCount(3);axisY->setMinorTickCount(4);axisY->setTitleText("value"); ?//為chart設置坐標軸chart->setAxisX(axisX, series0);chart->setAxisX(axisX, series1);chart->setAxisY(axisY, series0);chart->setAxisY(axisY, series1); }

為圖標添加數據

//更新數據 void MainWindow::prepareData() {//獲取chart表格的序列QLineSeries * series0 = (QLineSeries *)ui->chartview->chart()->series().at(0);QLineSeries * series1 = (QLineSeries *)ui->chartview->chart()->series().at(1); ?//為序列添加數據series0->clear();series1->clear();int cnt = 100;srand(QTime::currentTime().second());qreal t = 0, y1, y2, intv = 0.1;qreal rd;for (int i = 0; i < cnt; i++){rd=(qrand() % 10)-5; //隨機數,-5~+5y1=qSin(t)+rd/50;*series0<<QPointF(t,y1); ?//序列添加數據點 // ? ? ? series0->append(t,y1); //序列添加數據點 ?rd=(qrand() % 10)-5; //隨機數,-5~+5y2=qCos(t)+rd/50; // ? ? ? series1->append(t,y2); //序列添加數據點*series1<<QPointF(t,y2); //序列添加數據點t+=intv;} }

設置圖表和圖例

//設置圖表的標題 void MainWindow::on_btnSetTitle_clicked() {QChart * chart = ui->chartview->chart();chart->setTitle(ui->editTitle->text()); } ? //設置圖表標題字體 void MainWindow::on_btnSetTitleFont_clicked() {QFont font = ui->chartview->chart()->titleFont();bool ok =false;font = QFontDialog::getFont(&ok, font);if(ok){ui->chartview->chart()->setTitleFont(font);} } ? //設置圖例的位置 圖例為顯示曲線名字的一小塊區域 void MainWindow::on_radioButton_clicked() {ui->chartview->chart()->legend()->setAlignment(Qt::AlignTop); } void MainWindow::on_radioButton_2_clicked() {ui->chartview->chart()->legend()->setAlignment(Qt::AlignBottom); } void MainWindow::on_radioButton_3_clicked() {ui->chartview->chart()->legend()->setAlignment(Qt::AlignLeft); } void MainWindow::on_radioButton_4_clicked() {ui->chartview->chart()->legend()->setAlignment(Qt::AlignRight); } ? //設置圖例是否可見 void MainWindow::on_chkLegendVisible_clicked(bool checked) {ui->chartview->chart()->legend()->setVisible(checked); } //設置圖例背景是否可見 void MainWindow::on_chkBoxLegendBackground_clicked(bool checked) {ui->chartview->chart()->legend()->setBackgroundVisible(checked); } ? //設置圖例的字體 void MainWindow::on_btnLegendFont_clicked() {QFont font = ui->chartview->chart()->legend()->font();bool ok =false;font = QFontDialog::getFont(&ok, font);if(ok){ui->chartview->chart()->legend()->setFont(font);} } ? //設置圖例標簽顏色 void MainWindow::on_btnLegendlabelColor_clicked() {QColor color = ui->chartview->chart()->legend()->labelColor();color = QColorDialog::getColor(color);if(color.isValid()){ui->chartview->chart()->legend()->setLabelColor(color);} } ? //設置圖表的邊距 spinMarginBottom,spinMarginTop為QSpinBox用于控制邊距的距離 void MainWindow::on_btnSetMargin_clicked() {QMargins mgs;mgs.setBottom(ui->spinMarginBottom->value());mgs.setTop(ui->spinMarginTop->value());mgs.setLeft(ui->spinMarginLeft->value());mgs.setRight(ui->spinMarginRight->value());ui->chartview->chart()->setMargins(mgs); } ? //設置圖表的動畫效果 具體可以進入Qt函數進行了解 通過枚舉進行設置 void MainWindow::on_cBoxAnimation_currentIndexChanged(int index) {ui->chartview->chart()->setAnimationOptions((QChart::AnimationOption) index); } ? //設置圖表的主題 void MainWindow::on_cBoxTheme_currentIndexChanged(int index) {ui->chartview->chart()->setTheme(QChart::ChartTheme(index)); }

QDialgoPen獲取畫筆

//頭文件 #include <QDialog> #include <QPen> public:explicit DialogPen(QWidget *parent = nullptr);~DialogPen(); ?//使用靜態函數獲取畫筆static QPen getPen(QPen pen,bool & ok);void ? ?setPen(QPen pen); //設置QPen,用于對話框的界面顯示QPen ? ?getPen(); //獲取對話框設置的QPen的屬性 ? private:QPen m_pen; ? //cpp #include "dialogpen.h" #include "ui_dialogpen.h" #include <QColorDialog> ? DialogPen::DialogPen(QWidget *parent) :QDialog(parent),ui(new Ui::DialogPen) {ui->setupUi(this); ?//“線型”ComboBox的選擇項設置ui->comboPenStyle->clear();ui->comboPenStyle->addItem("NoPen",0);ui->comboPenStyle->addItem("SolidLine",1);ui->comboPenStyle->addItem("DashLine",2);ui->comboPenStyle->addItem("DotLine",3);ui->comboPenStyle->addItem("DashDotLine",4);ui->comboPenStyle->addItem("DashDotDotLine",5);ui->comboPenStyle->addItem("CustomDashLine",6); ?ui->comboPenStyle->setCurrentIndex(1); } ? DialogPen::~DialogPen() {delete ui; } ? //使用靜態函數獲取畫筆 QPen DialogPen::getPen(QPen inipen, bool &ok) {QPen pen;DialogPen * dlg = new DialogPen;dlg->setPen(inipen);int ret = dlg->exec();if(ret == QDialog::Accepted){pen = dlg->getPen();ok = true;}else{pen = inipen;ok = false;} ?delete ?dlg;return ?pen; } ? void DialogPen::setPen(QPen pen) { //設置QPen,并刷新顯示界面m_pen=pen; ?ui->spinWidth->setValue(pen.width()); //線寬int i=static_cast<int>(pen.style()); ?//枚舉類型轉換為整型ui->comboPenStyle->setCurrentIndex(i); ?QColor ?color=pen.color();ui->btnColor->setAutoFillBackground(true); //設置顏色按鈕的背景色QString str=QString::asprintf("background-color: rgb(%d, %d, %d);",color.red(),color.green(),color.blue());ui->btnColor->setStyleSheet(str); } ? QPen DialogPen::getPen() {//獲得設置的屬性m_pen.setStyle(Qt::PenStyle(ui->comboPenStyle->currentIndex())); //線型m_pen.setWidth(ui->spinWidth->value()); //線寬 ?QColor ?color;color=ui->btnColor->palette().color(QPalette::Button);m_pen.setColor(color); //顏色return ?m_pen; } ? //選擇顏色 void DialogPen::on_btnColor_clicked() {QColor color = m_pen.color();color = QColorDialog::getColor(color); ?if(color.isValid()){QString str = QString::asprintf("background-color: rgb(%d, %d, %d);", color.red(), color.green(), color.blue());ui->btnColor->setStyleSheet(str);} }

設置曲線和坐標點

//根據RadioButton判斷選中的是哪個曲線 void MainWindow::on_radioSeries0_clicked() {if(ui->radioSeries0->isChecked()){curSeries = (QLineSeries *)ui->chartview->chart()->series().at(0);}else{curSeries = (QLineSeries *)ui->chartview->chart()->series().at(1);} ?//獲取curSeries的值,更新界面ui->editSeriesName->setText(curSeries->name());ui->chkSeriesVisible->setChecked(curSeries->isVisible());ui->chkPointVisible->setChecked(curSeries->pointsVisible());ui->sliderSeriesOpacity->setValue(curSeries->opacity() * 10);ui->chkPointLabelVisible->setChecked(curSeries->pointLabelsVisible()); } void MainWindow::on_radioSeries1_clicked() {on_radioSeries0_clicked(); } ? //設置曲線的名字 void MainWindow::on_btnSeriesName_clicked() {curSeries->setName(ui->editSeriesName->text()); } ? //設置系列是否可見 void MainWindow::on_chkSeriesVisible_clicked(bool checked) {curSeries->setVisible(ui->chkSeriesVisible->isChecked()); } ? //設置數據點是否可見 void MainWindow::on_chkPointVisible_clicked(bool checked) {curSeries->setPointsVisible(ui->chkPointVisible->isChecked()); } ? //設置曲線顏色 void MainWindow::on_btnSeriesColor_clicked() {QColor color = curSeries->color();color = QColorDialog::getColor(color);if(color.isValid()){curSeries->setColor(color);} } ? //設置曲線的pen void MainWindow::on_btnSeriesPen_clicked() {bool ok = false;QPen pen = curSeries->pen();pen = DialogPen::getPen(pen, ok);if(ok){curSeries->setPen(pen);} } ? //改變曲線的透明度 void MainWindow::on_sliderSeriesOpacity_valueChanged(int value) {curSeries->setOpacity(value / 10.0); } ? //設置數據點標簽是否可見 數據點標簽是在曲線周圍顯示曲線的x,y的標簽 void MainWindow::on_chkPointLabelVisible_clicked(bool checked) {curSeries->setPointLabelsVisible(checked); } ? //設置數據點標簽的顏色 void MainWindow::on_btnSeriesLabColor_clicked() {QColor color = curSeries->pointLabelsColor();color = QColorDialog::getColor(color);if(color.isValid()){curSeries->setPointLabelsColor(color);} } ? //設置數據點標簽字體 void MainWindow::on_btnSeriesLabFont_clicked() {QFont font = curSeries->pointLabelsFont();bool ok = false;font = QFontDialog::getFont(&ok, font);if(ok){curSeries->setPointLabelsFont(font);} } ? //根據RadioButton選擇的是哪個設置數據點標簽樣式 顯示y的值 顯示x和y的值 //"@xPoint, @yPoint" 10,20 無括號 "(@xPoint, @yPoint)" (10, 20)有括號 void MainWindow::on_radioSeriesLabFormat0_clicked() {if(ui->radioSeriesLabFormat0->isChecked()){curSeries->setPointLabelsFormat("@yPoint");}else{curSeries->setPointLabelsFormat("(@xPoint, @yPoint)");} } void MainWindow::on_radioSeriesLabFormat1_clicked() {on_radioSeriesLabFormat0_clicked(); }

設置坐標軸

坐標軸分為x軸和y軸,根據QValueAxis獲取x軸或y軸。

坐標軸有兩種網格線,一種是大格子,一種是小格子,小格子為大格子再切分,setTickCount設置大格子條數,setMinorTickCount設置小格子條數。具體案例參考samp9_2

QValueAxis * curAxis; //根據RadioButton選擇的是x軸還是y軸進行設置 void MainWindow::on_radioX_clicked() {//獲取當前坐標軸// 在Qt 5.12.1中編譯時提示 QChart::axisX()和QChart::axisY()函數過時,應使用 QChart::axes()函數// ? if (ui->radioX->isChecked())// ? ? ? curAxis=(QValueAxis*)ui->chartView->chart()->axisX();// ? else// ? ? ? curAxis=(QValueAxis*)ui->chartView->chart()->axisY(); ?// 下面是針對Qt 5.12.1修改的代碼,在Qt5.9.1里編譯也沒問題QList<QAbstractAxis*> axes;if (ui->radioX->isChecked())axes=ui->chartview->chart()->axes(Qt::Horizontal);elseaxes=ui->chartview->chart()->axes(Qt::Vertical);curAxis=(QValueAxis*)axes[0]; ? ?//獲取坐標軸的各種屬性,顯示到界面上ui->spinAxisMin->setValue(curAxis->min());ui->spinAxisMax->setValue(curAxis->max()); ?ui->editAxisTitle->setText(curAxis->titleText());ui->chkBoxAxisTitle->setChecked(curAxis->isTitleVisible()); ?ui->editAxisLabelFormat->setText(curAxis->labelFormat());ui->chkBoxLabelsVisible->setChecked(curAxis->labelsVisible()); ?ui->chkGridLineVisible->setChecked(curAxis->isGridLineVisible());ui->chkAxisLineVisible->setChecked(curAxis->isLineVisible()); ?ui->spinTickCount->setValue(curAxis->tickCount());ui->chkAxisLineVisible->setChecked(curAxis->isLineVisible()); ?ui->spinMinorTickCount->setValue(curAxis->minorTickCount());ui->chkMinorTickVisible->setChecked(curAxis->isMinorGridLineVisible()); } void MainWindow::on_radioY_clicked() {on_radioX_clicked(); } ? //設置坐標軸是否可見 void MainWindow::on_chkBoxVisible_clicked(bool checked) {curAxis->setVisible(checked); } ? //設置坐標軸的范圍 void MainWindow::on_btnSetAxisRange_clicked() {curAxis->setRange(ui->spinAxisMin->value(), ui->spinAxisMax->value()); } ? //設置坐標軸的標題 void MainWindow::on_btnAxisSetTitle_clicked() {curAxis->setTitleText(ui->editAxisTitle->text()); } ? //設置坐標軸標題是否可見 void MainWindow::on_chkBoxAxisTitle_clicked(bool checked) {curAxis->setTitleVisible(checked); } ? //設置軸刻度標簽格式 void MainWindow::on_pushButton_clicked() {curAxis->setLabelFormat(ui->editAxisLabelFormat->text()); } ? //設置軸刻度標簽文字的顏色 void MainWindow::on_btnAxisLabelColor_clicked() {QColor color= curAxis->labelsColor();color = QColorDialog::getColor(color);if (color.isValid())curAxis->setLabelsColor(color); } ? //設置軸刻度標簽文字的字體 void MainWindow::on_btnAxisLabelFont_clicked() {QFont font=curAxis->labelsFont();bool ok=false;font=QFontDialog::getFont(&ok,font);if (ok)curAxis->setLabelsFont(font); } ? //設置軸刻度標簽是否可見 void MainWindow::on_chkBoxLabelsVisible_clicked(bool checked) {curAxis->setLabelsVisible(checked); } ? //設置坐標軸網格線的顏色 void MainWindow::on_btnGridLineColor_clicked() {QColor color = curAxis->gridLineColor();color = QColorDialog::getColor(color);if (color.isValid())curAxis->setGridLineColor(color); } ? //設置坐標軸網格線的pen void MainWindow::on_pushButton_10_clicked() {QPen pen;pen = curAxis->gridLinePen();bool ok=false;pen = DialogPen::getPen(pen,ok);if (ok)curAxis->setGridLinePen(pen); } ? //設置坐標軸大格子豎線的數量 void MainWindow::on_spinTickCount_valueChanged(int arg1) {curAxis->setTickCount(arg1); } ? //設置坐標軸小格子豎線的數量 void MainWindow::on_spinMinorTickCount_valueChanged(int arg1) {curAxis->setMinorTickCount(arg1); } ? //設置坐標軸線是否可見 void MainWindow::on_chkAxisLineVisible_clicked(bool checked) {curAxis->setLineVisible(checked); } ? //設置坐標軸線的pen void MainWindow::on_btnAxisLinePen_clicked() {QPen pen;pen = curAxis->linePen();bool ok = false;pen = DialogPen::getPen(pen, ok);if (ok)curAxis->setLinePen(pen); } ? //設置坐標軸線的顏色 void MainWindow::on_btnAxisLinePenColor_clicked() {QColor color = curAxis->linePenColor();color = QColorDialog::getColor(color);if(color.isValid())curAxis->setLinePenColor(color); } ? //設置坐標軸小格子線是否可見 void MainWindow::on_chkMinorTickVisible_clicked(bool checked) {curAxis->setMinorGridLineVisible(checked); } ? //設置坐標軸小格子線的顏色 void MainWindow::on_btnMinorColor_clicked() {QColor color = curAxis->minorGridLineColor();color = QColorDialog::getColor(color);if(color.isValid())curAxis->setMinorGridLineColor(color); } ? //設置坐標軸小格子線的pen void MainWindow::on_btnMinorPen_clicked() {QPen pen;pen = curAxis->minorGridLinePen();bool ok = false;pen = DialogPen::getPen(pen, ok);if (ok)curAxis->setMinorGridLinePen(pen); } ?

常見圖表的繪制

QBarChart

QBarChart為柱狀圖,可以顯示多個柱狀圖,通過QBarSet設置數據,QBarSeries添加QBarSet數據集

通過QStandardItemModel設置數據

//頭文件 #include ? <QStandardItemModel> #include ? <QItemSelectionModel> ? #include ? <QtCharts> ?//必須這么設置 QT_CHARTS_USE_NAMESPACE ? #define ? ? fixedColumnCount ? 5 ? ?//數據模型的列數 #define ? ? iniDataRowCount ? 6 ? //學生個數 ? #define ? ? colNoName ? ? ? 0 ? //姓名的列編號 #define ? ? colNoMath ? ? ? 1 ? //數學的列編號 #define ? ? colNoChinese ? 2 ? //語文的列編號 #define ? ? colNoEnglish ? 3 ? //英語的列編號 #define ? ? colNoAverage ? 4 ? //平均分的列編號QStandardItemModel ?*theModel;//數據模型 ? void ? ?iniData();//初始化數據 void ? ?surveyData();//統計數據 ? void ? ?iniBarChart(); //柱狀圖初始化 void ? ?buildBarChart();//構建柱狀圖 ? //cpp //初始化數據 void MainWindow::iniData() {//為model設置表頭QStringList headerList;headerList<<"姓名"<<"數學"<<"語文"<<"英語"<<"平均分";theModel->setHorizontalHeaderLabels(headerList); ?//為model添加數據for (int i = 0; i < theModel->rowCount(); i++){QString stuName = QString::asprintf("學生%2d", i + 1);QStandardItem * aItem = new QStandardItem(stuName);aItem->setTextAlignment(Qt::AlignHCenter);theModel->setItem(i, colNoName, aItem);qreal avgScore = 0;for (int j = colNoMath; j <= colNoEnglish; j++){qreal score = 50 + qrand() % 50;//隨機生成一個50-99的數aItem = new QStandardItem(QString::asprintf("%.0f", score));aItem->setTextAlignment(Qt::AlignHCenter);theModel->setItem(i, j, aItem);avgScore += score;} ?//求取平均分進行填充aItem = new QStandardItem(QString::asprintf("%.1f", avgScore/3));aItem->setTextAlignment(Qt::AlignHCenter); ?//設置平均分數據不可修改aItem->setFlags(aItem->flags() & !Qt::ItemIsEditable);theModel->setItem(i, colNoAverage, aItem);} } ? //統計數據 void MainWindow::surveyData() {for (int i = colNoMath; i <= colNoAverage; i++){qreal minVal = 100, maxVal = 0, val, sum = 0;int cnt50 = 0, cnt60 =0, cnt70 = 0, cnt80 = 0, cnt90 = 0;for (int j = 0; j < theModel->rowCount(); j++){val = theModel->item(j, i)->text().toDouble();if(val > maxVal) maxVal = val;if(val < minVal) minVal = val; ?if(val < 60) cnt50++;else if(val < 70) cnt60++;else if(val < 80) cnt70++;else if(val < 90) cnt80++;else cnt90++;sum += val;} ?//選擇設計的Qtree只有父節點 所以都是topLevelItemQTreeWidgetItem * aItem = ui->treeWidget->topLevelItem(0);aItem->setTextAlignment(i, Qt::AlignHCenter);aItem->setText(i, QString::number(cnt50)); ?aItem = ui->treeWidget->topLevelItem(1);aItem->setTextAlignment(i, Qt::AlignHCenter);aItem->setText(i, QString::number(cnt60)); ?aItem = ui->treeWidget->topLevelItem(2);aItem->setTextAlignment(i, Qt::AlignHCenter);aItem->setText(i, QString::number(cnt70)); ?aItem = ui->treeWidget->topLevelItem(3);aItem->setTextAlignment(i, Qt::AlignHCenter);aItem->setText(i, QString::number(cnt80)); ?aItem = ui->treeWidget->topLevelItem(4);aItem->setTextAlignment(i, Qt::AlignHCenter);aItem->setText(i, QString::number(cnt90)); ?aItem = ui->treeWidget->topLevelItem(5);aItem->setTextAlignment(i, Qt::AlignHCenter);aItem->setText(i, QString::number(sum / iniDataRowCount)); ?aItem = ui->treeWidget->topLevelItem(6);aItem->setTextAlignment(i, Qt::AlignHCenter);aItem->setText(i, QString::number(maxVal)); ?aItem = ui->treeWidget->topLevelItem(7);aItem->setTextAlignment(i, Qt::AlignHCenter);aItem->setText(i, QString::number(minVal));} } ? //初始化數據 void MainWindow::on_actGenData_triggered() {iniData(); } ? //統計數據 void MainWindow::on_actTongJi_triggered() {surveyData(); }

繪制柱狀圖(BarChart)

//初始化柱狀圖 chartViewBar為QChartView控件 void MainWindow::iniBarChart() {QChart * chart = new QChart;chart->setTitle("Barchart演示"); ?//設置動畫效果chart->setAnimationOptions(QChart::SeriesAnimations);ui->chartViewBar->setChart(chart); ?//設置抗鋸齒模式ui->chartViewBar->setRenderHint(QPainter::Antialiasing); } ? //構建柱狀圖 void MainWindow::buildBarChart() {QChart * chart = ui->chartViewBar->chart(); ?//先清除chart,因為經常要刷新,可能會形成多個坐標軸chart->removeAllSeries();if(chart->axisX() != NULL){chart->removeAxis(chart->axisX());chart->removeAxis(chart->axisY());} ?//數據集 QBarSet用于顯示柱狀圖即三門課的成績 QLineSeries用于顯示折線圖即平均分QBarSet * setMath = new QBarSet(theModel->horizontalHeaderItem(colNoMath)->text());QBarSet * setChinese = new QBarSet(theModel->horizontalHeaderItem(colNoChinese)->text());QBarSet * setEnglish = new QBarSet(theModel->horizontalHeaderItem(colNoEnglish)->text());QLineSeries * Line = new QLineSeries; ?//為QLineSeries設置penQPen pen;pen.setColor(Qt::red);pen.setWidth(2);Line->setPen(pen);Line->setName(theModel->horizontalHeaderItem(colNoAverage)->text()); ?//從model從取到數據,為序列添加數據for (int i = 0; i < theModel->rowCount(); i++){setMath->append(theModel->item(i, colNoMath)->text().toInt());setChinese->append(theModel->item(i, colNoChinese)->text().toInt());setEnglish->append(theModel->item(i, colNoEnglish)->text().toInt());Line->append(QPointF(i, theModel->item(i, colNoMath)->text().toFloat()));} ?//序列QBarSeries * seriers = new QBarSeries;seriers->append(setMath);seriers->append(setChinese);seriers->append(setEnglish); ?//為chartview添加序列chart->addSeries(seriers);chart->addSeries(Line); ?//設置坐標軸 QBarCategoryAxis為x軸 QValueAxis為Y軸QStringList categories;for(int i = 0; i < theModel->rowCount(); i++){categories<< theModel->item(i, colNoName)->text();} ?QBarCategoryAxis * axisX = new QBarCategoryAxis;axisX->setCategories(categories);chart->setAxisX(axisX, seriers);chart->setAxisX(axisX, Line); ?QValueAxis * axisY = new QValueAxis;axisY->setRange(0, 100);axisY->setTitleText("分數");chart->setAxisY(axisY, seriers);chart->setAxisY(axisY, Line); ?//設置標簽位于表格下面chart->legend()->setAlignment(Qt::AlignBottom); }

繪制餅狀圖(QPieChart)

餅狀圖主要通過QPieSeries來設置數據,chart添加QPieSeries,為餅狀圖添加餅狀塊通過QPieSeries的a QPieSlice *QPieSeries::append(QString label, qreal value) 函數, 繪制餅狀圖時,需要繪制的對象都是一個系列series,使用apppend函數添加,第一個參數是series的名稱,第二個參數是這個系列所占的比例大小float類型

//構建餅圖 void MainWindow::buildPieChart() {QChart * chart = ui->chartViewPie->chart(); ?//先清除chart,因為經常要刷新,可能會形成多個坐標軸chart->removeAllSeries();if(chart->axisX() != NULL){chart->removeAxis(chart->axisX());chart->removeAxis(chart->axisY());} ?//為QpieChart準備數據QPieSeries * seriers = new QPieSeries; ?//設置餅狀圖中間空白圓圈的大小seriers->setHoleSize(ui->spinHoleSize->value()); ?//設置餅狀圖的大小seriers->setPieSize(ui->spinPieSize->value()); ?//獲取CheckBOX選中的科目int colNo = ui->cBoxCourse->currentIndex() + 1;for(int i = 0; i < 5; i++){QTreeWidgetItem * item = ui->treeWidget->topLevelItem(i); ?//繪制餅狀圖時,需要繪制的對象都是一個系列series,使用apppend函數添加,//第一個參數是series的名稱,第二個參數是這個系列所占的比例大小float類型//QPieSeries的append函數相當于就是添加了QPieSlice餅狀塊seriers->append( item->text(0), item->text(colNo).toFloat() );} ?//設置餅狀塊QPieSlice * slice;for (int i =0; i < 5; i++){//獲取分塊slice =seriers->slices().at(i); ?//設置分塊的標簽slice->setLabel(slice->label()+QString::asprintf(": %.0f人, %.1f%%",slice->value(),slice->percentage()*100)); ?//當鼠標略過的時候,顯示突出connect(slice, SIGNAL(hovered(bool)), this, SLOT(on_PieSliceHighlight(bool )));} ?//最后一個設置為explodedslice->setExploded(true); ?//只影響當前的slices,必須添加完slice之后再設置seriers->setLabelsVisible(true); ?//設置標題為當前展示的科目chart->setTitle("PieChart-------" + ui->cBoxCourse->currentText()); ?//為餅狀圖添加序列chart->addSeries(seriers); ?//將標簽放在餅狀圖右邊chart->legend()->setAlignment(Qt::AlignRight); } ? void MainWindow::on_btnDrawPieChart_clicked() {iniPiewChart();buildPieChart(); } ? //當鼠標掠過餅塊時突出顯示 void MainWindow::on_PieSliceHighlight(bool show) {//獲取掠過的餅塊QPieSlice * slice = (QPieSlice*)sender(); ?//設置是否突出顯示slice->setExploded(show); } ? //根據槽函數設置餅狀圖內部圓圈大小 void MainWindow::on_spinHoleSize_valueChanged(double arg1) {QPieSeries * series;series = (QPieSeries *)ui->chartViewPie->chart()->series().at(0);series->setHoleSize(arg1); } ? //根據槽函數設置餅狀圖圓圈大小 void MainWindow::on_spinPieSize_valueChanged(double arg1) {QPieSeries * series;series = (QPieSeries *)ui->chartViewPie->chart()->series().at(0);series->setPieSize(arg1); } ? //根據枚舉量設置主題 void MainWindow::on_cBoxTheme_currentIndexChanged(int index) {ui->chartViewPie->chart()->setTheme(QChart::ChartTheme(index)); }

繪制堆積圖(QStackedBar)

堆積圖是指一個柱狀圖里面包括多份數據,可以用來設置一個學生的總分,根據堆積圖可以清晰地看出每個學生的每門科目的分數及總分。

//堆積圖初始化 void MainWindow::iniStackedBar() {QChart * chart = new QChart;chart->setTitle("Stackedchart演示"); ?//設置動畫效果chart->setAnimationOptions(QChart::SeriesAnimations);ui->chartViewStackedBar->setChart(chart); ?//設置抗鋸齒模式ui->chartViewStackedBar->setRenderHint(QPainter::Antialiasing); } ? //構建堆積圖 void MainWindow::buildStackedBar() {QChart * chart = ui->chartViewStackedBar->chart(); ?//先清除chart,因為經常要刷新,可能會形成多個坐標軸chart->removeAllSeries();if(chart->axisX() != NULL){chart->removeAxis(chart->axisX());chart->removeAxis(chart->axisY());} ?//數據集 QBarSet用于顯示柱狀圖即三門課的成績QBarSet * setMath = new QBarSet(theModel->horizontalHeaderItem(colNoMath)->text());QBarSet * setChinese = new QBarSet(theModel->horizontalHeaderItem(colNoChinese)->text());QBarSet * setEnglish = new QBarSet(theModel->horizontalHeaderItem(colNoEnglish)->text()); ?//為堆積圖添加數據集QStringList categories;for(int i = 0; i < theModel->rowCount(); i++){categories << theModel->item(i, colNoName)->text();setMath->append(theModel->item(i, colNoMath)->text().toFloat());setChinese->append(theModel->item(i, colNoChinese)->text().toFloat());setEnglish->append(theModel->item(i, colNoEnglish)->text().toFloat());} ?QStackedBarSeries * series = new QStackedBarSeries;series->append(setMath);series->append(setChinese);series->append(setEnglish); ?//添加坐標軸QBarCategoryAxis * axisX = new QBarCategoryAxis;axisX->append(categories);chart->setAxisX(axisX, series); ?QValueAxis *axisY = new QValueAxis;axisY->setRange(0, 300);axisY->setTitleText("總分");chart->setAxisY(axisY); ? ?//為表格添加序列化chart->addSeries(series); }

繪制百分比堆積圖(QPercentBar)

QPercentBar類似于QStackedBar,但是QPercentBar顯示的是各個部分占總部分的百分比。

//初始化 void MainWindow::iniPercentBar() {QChart * chart = new QChart;chart->setTitle("PercentBar演示"); ?//設置動畫效果chart->setAnimationOptions(QChart::SeriesAnimations);ui->chartViewPercentBar->setChart(chart); ?//設置抗鋸齒模式ui->chartViewPercentBar->setRenderHint(QPainter::Antialiasing); } ? //構建圖表 void MainWindow::buildPercentBar() {QChart * chart = ui->chartViewPercentBar->chart(); ?//先清除chart,因為經常要刷新,可能會形成多個坐標軸chart->removeAllSeries();if(chart->axisX() != NULL){chart->removeAxis(chart->axisX());chart->removeAxis(chart->axisY());} ?//數據集 QBarSet用于顯示柱狀圖即三門課的成績QBarSet * setMath = new QBarSet(theModel->horizontalHeaderItem(colNoMath)->text());QBarSet * setChinese = new QBarSet(theModel->horizontalHeaderItem(colNoChinese)->text());QBarSet * setEnglish = new QBarSet(theModel->horizontalHeaderItem(colNoEnglish)->text()); ?//為堆積圖添加數據集QStringList categories;for(int i = 0; i < 5; i++){categories << ui->treeWidget->topLevelItem(i)->text(colNoName);setMath->append(ui->treeWidget->topLevelItem(i)->text(colNoMath).toFloat());setChinese->append(ui->treeWidget->topLevelItem(i)->text(colNoChinese).toFloat());setEnglish->append(ui->treeWidget->topLevelItem(i)->text(colNoEnglish).toFloat());} ?QStackedBarSeries * series = new QStackedBarSeries;series->append(setMath);series->append(setChinese);series->append(setEnglish); ?//添加坐標軸QBarCategoryAxis * axisX = new QBarCategoryAxis;axisX->append(categories);chart->setAxisX(axisX, series); ?QValueAxis *axisY = new QValueAxis;axisY->setRange(0, 100);axisY->setTitleText("分數");chart->setAxisY(axisY); ? ?//為表格添加序列化chart->addSeries(series); }

繪制散點圖(Scatterchart)

散點采用QScatterSeries,可以對散點大小及樣式進行設置,使用append進行添加點,表格addSeries將序列加入。

//初始化 void MainWindow::iniScatterChart() {QChart * chart = new QChart;chart->setTitle("ScatterChart演示"); ?//設置動畫效果chart->setAnimationOptions(QChart::SeriesAnimations);ui->chartViewStackedBar->setChart(chart); ?//設置抗鋸齒模式ui->chartViewStackedBar->setRenderHint(QPainter::Antialiasing); } ? //構建圖表 void MainWindow::buildScatterChart() {//獲取ScatterChart指針QChart * chart = ui->chartViewScatter->chart(); ?//清除之前的序列chart->removeAllSeries(); ?//防止出現多個坐標軸if(chart->axisX() != NULL){chart->removeAxis(chart->axisX());chart->removeAxis(chart->axisY());} ?//設置線的樣式QSplineSeries * seriesLine = new QSplineSeries;seriesLine->setName("spline");QPen pen;pen.setWidth(2);pen.setColor(Qt::red);seriesLine->setPen(pen); ?//設置散點的樣式QScatterSeries * series0 = new QScatterSeries;series0->setName("散點");series0->setMarkerShape(QScatterSeries::MarkerShapeCircle);series0->setBorderColor(Qt::black);series0->setBrush(Qt::blue); ?//設置大小series0->setMarkerSize(12); ?//添加數據for(int i = 0; i < 10; i++){int x = qrand() % 20;int y = qrand() % 20;series0->append(x, y);seriesLine->append(x, y);} ?//為表格添加序列chart->addSeries(series0);chart->addSeries(seriesLine); ?//創建默認坐標軸chart->createDefaultAxes();chart->axisX()->setTitleText("X軸");chart->axisX()->setRange(-2, 22);chart->axisY()->setTitleText("Y軸");chart->axisY()->setRange(-2, 22); }

總結

以上是生活随笔為你收集整理的Qt学习心得的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

人人舔人人干 | 天天摸日日摸人人看 | 免费久草视频 | 日韩最新在线视频 | 亚洲午夜精品在线观看 | 日韩精品中文字幕av | 人人干人人草 | 欧美成人一区二区 | 国产午夜影院 | free,性欧美 九九交易行官网 | 激情网色 | 九九免费在线观看视频 | 国产第一页在线播放 | 黄色特级一级片 | 国产久视频 | 成人一级免费电影 | 永久免费观看视频 | 99热这里| 麻豆成人精品视频 | 97av在线视频免费播放 | 久久久久久久久久久久影院 | 99久久夜色精品国产亚洲 | av久久在线| 综合色婷婷 | 91精品国产一区二区在线观看 | 国产免费久久精品 | 亚洲高清视频在线播放 | 91黄色影视 | 精品在线视频播放 | 亚洲人视频在线 | 日本久久精品 | 亚洲黄色激情小说 | 激情伊人五月天久久综合 | 香蕉视频久久 | 天天干天天操天天操 | 精品国产免费久久 | 欧美少妇xxx | 99精品国自产在线 | 欧美日韩在线观看视频 | 国产综合视频在线观看 | 九九视频免费观看视频精品 | 国色综合 | 色88久久 | 色噜噜狠狠狠狠色综合 | 手机看片国产日韩 | 久久999精品 | 欧美日韩国产综合网 | 久久神马影院 | 色国产视频 | 免费成视频 | 久久久久久国产精品 | 国产人在线成免费视频 | 精品一二三四五区 | 国产精品一级在线 | 国际精品网 | 91大神精品视频 | 亚洲综合一区二区精品导航 | 一区二区三区精品久久久 | 成人在线免费看 | 在线观看成年人 | 超碰免费在线公开 | 日韩欧美视频免费在线观看 | 国产亚洲在线 | 久久久久久美女 | 91精品入口 | 国产97色在线 | 中文视频在线播放 | 三级av黄色 | 精品视频免费看 | 一 级 黄 色 片免费看的 | 国产精品18久久久久久久网站 | 国产精品一区二区三区免费看 | 四川bbb搡bbb爽爽视频 | 久久99国产精品视频 | 免费观看www小视频的软件 | 日韩免费电影一区二区 | 99精品视频在线播放观看 | 色偷偷88欧美精品久久久 | 国内精品久久久久久久久久 | 一区在线播放 | 日本激情视频中文字幕 | 欧美激情一区不卡 | 免费视频久久 | 91九色网站| 久久网址 | 亚洲精品在线电影 | 久久人人添人人爽添人人88v | 99色在线观看 | 在线看一区二区 | 五月天久久综合 | 亚洲免费在线视频 | 男女激情片在线观看 | 日韩精品1区2区 | 国产精品国产三级国产 | 91av蜜桃 | 日韩一级片观看 | 四虎影视精品永久在线观看 | 精品一区二区免费 | 日韩电影在线观看中文字幕 | av成人动漫在线观看 | 午夜.dj高清免费观看视频 | 天天色天天干天天色 | 国产黄色成人 | 亚洲精品欧美视频 | 极品中文字幕 | 成年人在线免费视频观看 | 人人干狠狠干 | 99久久精品国产亚洲 | 久久综合久色欧美综合狠狠 | 人人讲 | 久久艹在线观看 | 超碰97免费在线 | 少妇超碰在线 | 有没有在线观看av | 色片网站在线观看 | 久久久国产一区二区三区四区小说 | 热久久视久久精品18亚洲精品 | 亚洲国产日韩欧美 | 欧美精品国产精品 | 一区二区三区在线视频111 | 去看片 | 探花视频免费在线观看 | 久久久精品 一区二区三区 国产99视频在线观看 | 色99导航| 色五月色开心色婷婷色丁香 | 91成人黄色 | 国产手机精品视频 | 日本精品久久久久中文字幕5 | 日韩成人精品在线观看 | 一个色综合网站 | 亚洲精品国产麻豆 | 久久久久久不卡 | 91系列在线观看 | 天天干天天操人体 | www.99热精品 | 超碰在线观看99 | 国产99久久九九精品免费 | 五月导航 | 久久成人一区二区 | 91精品推荐| 久久精品高清视频 | 中文字幕一区二区三区精华液 | 激情视频一区二区三区 | 尤物97国产精品久久精品国产 | 久久久午夜精品福利内容 | 人人草在线观看 | av网站免费在线 | 免费福利视频网站 | 国产成人99久久亚洲综合精品 | 国产精品18久久久久白浆 | 91九色网址| 手机av在线免费观看 | 黄色的视频 | 人人精品久久 | 国产高清在线一区 | 国产中文字幕在线视频 | 久久99国产一区二区三区 | 国产精品久久网 | 日韩xxxx视频 | 久久影院一区 | 国产91粉嫩白浆在线观看 | 日韩一区视频在线 | www178ccom视频在线 | 国产精品久久久久毛片大屁完整版 | 欧美亚洲一级片 | 婷婷激情5月天 | 99r在线精品| 91麻豆精品国产91 | 欧美激情va永久在线播放 | 精品高清美女精品国产区 | 成年人免费电影在线观看 | 日韩丝袜视频 | 国内精品久久久久国产 | 欧美日韩久久久 | 97日日| 成人免费xxxxxx视频 | 午夜私人影院 | 亚洲在线a | 99福利影院 | 日本午夜免费福利视频 | 天天色天天射综合网 | 国产无套视频 | 色多多在线观看 | 欧美日韩国产成人 | 午夜精品在线看 | 成人av在线观 | 日韩av成人在线观看 | 国产一区二区三区高清播放 | www.人人草| 五月婷婷影院 | 四虎成人精品永久免费av | 久久久久久久久毛片精品 | 高清av中文字幕 | 日韩欧美一区二区三区黑寡妇 | 国产精品毛片一区二区 | 亚洲精品九九 | 视频 国产区 | 成人h动漫精品一区二 | 五月开心网 | 欧美视频在线观看免费网址 | 色噜噜噜噜 | 欧美日韩一区二区视频在线观看 | 色99色 | 国产精品成人免费一区久久羞羞 | 亚洲精品在线看 | 国产97在线看 | 在线 国产 亚洲 欧美 | 黄色三级免费看 | 国产精品久久久久久影院 | 国产精品激情 | 国产一级片播放 | 男女精品久久 | 久久亚洲精品国产亚洲老地址 | 国产精品99久久99久久久二8 | 日韩久久久久久久久 | 99精品在这里 | 久久久午夜电影 | 色99久久 | 国产成人精品av | 日本护士三级少妇三级999 | 中文一区二区三区在线观看 | 国产精品一区二区三区四 | 午夜久久影院 | 狠狠的干狠狠的操 | 亚洲国产日韩一区 | 亚洲精品字幕在线观看 | 在线看日韩 | 一级久久精品 | 久久精品成人热国产成 | www欧美xxxx| av高清免费在线 | 久久婷婷国产色一区二区三区 | 精品91视频 | www久久久| 亚洲高清视频一区二区三区 | 亚洲激情久久 | 福利一区二区三区四区 | 中文字幕色网站 | 国产理论免费 | 成人午夜电影在线播放 | 五月天综合激情网 | 在线免费黄色毛片 | 国产黄在线看 | 亚洲欧美va| 成人av电影免费在线播放 | 91精品区| 99久久久久久国产精品 | 国产精品麻豆果冻传媒在线播放 | 五月天激情综合 | 久章草在线观看 | 亚洲国产高清视频 | 国产亚洲精品xxoo | 国产成本人视频在线观看 | 99在线高清视频在线播放 | 免费看高清毛片 | 久久高清免费视频 | 中文av字幕在线观看 | 在线免费试看 | 在线精品观看国产 | 天天射天 | 开心激情综合网 | 日韩免费三区 | 欧美日韩国产在线一区 | 99久精品视频 | 国产一区二区电影在线观看 | 婷婷久久综合九色综合 | 国产精品99久久免费黑人 | 九色视频网 | 久久另类小说 | 久久久精品国产免费观看同学 | 亚洲精品免费在线观看视频 | 91av国产视频 | 狠狠操电影网 | 欧美国产日韩一区二区三区 | 久久久久成人精品免费播放动漫 | 国产高清精 | 亚洲激情校园春色 | 亚洲禁18久人片 | 国产麻豆视频 | 黄色一级大片在线免费看国产一 | 亚洲资源视频 | 天天爽夜夜爽人人爽曰av | 国产精品色在线 | 亚洲 欧美 日韩 综合 | 97电影手机 | 97av.com | 西西www444| 日韩两性视频 | 亚洲综合成人婷婷小说 | 欧美三级免费 | 五月综合婷 | 久久九九免费视频 | 亚洲免费观看在线视频 | 在线影院中文字幕 | 激情五月婷婷丁香 | 日韩最新在线视频 | 久久高清片 | 在线一二三四区 | 青青久草在线视频 | 99久久影视| 精品国偷自产国产一区 | 制服丝袜欧美 | 91理论电影 | 狠狠躁日日躁狂躁夜夜躁 | 六月丁香婷婷网 | 亚洲爱av | 一区二区久久久久 | 激情欧美一区二区三区免费看 | 黄污在线观看 | a级片韩国 | 国产一区二区在线免费 | 亚洲久在线 | 在线看成人 | a视频在线观看 | 欧美一区二区三区四区夜夜大片 | 91亚洲免费 | 亚洲四虎在线 | 人人涩 | 国产破处在线播放 | 亚洲夜夜综合 | 国精产品999国精产品视频 | 久久久久久久毛片 | 亚洲欧美偷拍另类 | 日本激情中文字幕 | 91麻豆国产福利在线观看 | 日本在线免费看 | 欧美日韩国产精品一区 | 免费a级大片 | 五月婷社区 | 一区在线电影 | 色综合久久久久久久久五月 | 久久情爱| 国产黄色精品 | 91av视屏| 天天操操操操操 | 国产成本人视频在线观看 | 毛片1000部免费看 | 欧美国产日韩一区二区三区 | 六月久久婷婷 | 亚洲日本韩国一区二区 | 亚洲理论在线观看 | 在线观看免费一区 | 国产精品24小时在线观看 | 在线观看成人国产 | 蜜桃av久久久亚洲精品 | 最近免费观看的电影完整版 | 欧美精品免费视频 | 欧美国产日韩激情 | 国产91精品一区二区 | 免费看v片网站 | www.夜色321.com | 91视频免费看片 | 亚洲精品99久久久久中文字幕 | 丁香花在线视频观看免费 | 999久久久免费精品国产 | 天天干天天操天天做 | 国产精品视频在线看 | 日本激情视频中文字幕 | 久久高清免费观看 | 激情久久久久 | 国产三级精品三级在线观看 | 国产高清视频网 | 免费福利在线播放 | av电影免费| 97超碰免费在线观看 | 久久精品国产亚洲 | 人人澡人人模 | 超碰免费久久 | 色综合国产| 欧美综合干 | 午夜三级影院 | 91大神精品视频 | 久久综合久久综合九色 | 激情av网 | 天天射天天爽 | 日韩av不卡在线 | 97高清免费视频 | 中文字幕 国产视频 | 天天草综合网 | 黄色av电影在线 | 色网av| 99精品视频在线免费观看 | 国产精品久久久毛片 | 在线观看aa | 欧女人精69xxxxxx | 亚洲精品美女久久 | 亚洲久草视频 | 久久激情五月丁香伊人 | 亚洲va天堂va欧美ⅴa在线 | 激情动态 | 国产精品欧美久久久久天天影视 | 深爱激情五月综合 | 日本视频久久久 | 久草在线视频免费资源观看 | 五月天伊人网 | 亚洲区另类春色综合小说 | 国产视频69 | 日韩中文字幕国产精品 | 婷婷六月激情 | 99久久精品免费看国产四区 | 香蕉视频在线看 | 四虎成人精品永久免费av | 美女视频黄频大全免费 | 天天色宗合 | 亚洲天天在线日亚洲洲精 | 91手机视频在线 | 国产精品丝袜在线 | 91高清免费在线观看 | 青草视频免费观看 | 日韩极品视频在线观看 | 国产精品久久久久9999 | av日韩中文| 亚洲做受高潮欧美裸体 | 激情久久五月天 | 久久99精品久久久久久秒播蜜臀 | 免费无遮挡动漫网站 | 亚洲砖区区免费 | 成片人卡1卡2卡3手机免费看 | 天天射天天射 | 国产不卡在线视频 | 一本一本久久a久久精品综合小说 | 亚洲精品视频在线播放 | 久久黄色美女 | 天天夜夜操 | 国产一区免费观看 | 日韩爱爱片 | 去干成人网 | 黄色福利网 | 蜜臀av性久久久久av蜜臀妖精 | 伊人伊成久久人综合网小说 | 色综合久久久久网 | adc在线观看 | 黄色大片日本 | 毛片在线播放网址 | 成人黄色电影免费观看 | 好看的国产精品视频 | 不卡电影免费在线播放一区 | 欧美日韩一区二区三区在线免费观看 | 91视频麻豆 | 久久精品毛片基地 | 中文字幕国产在线 | 亚洲成人精品在线观看 | 欧美一二区在线 | 在线99视频 | 精品久久久久久亚洲综合网站 | 婷婷亚洲五月色综合 | 色狠狠一区二区 | 中文字幕亚洲精品在线观看 | 99久久9 | 亚洲精品av在线 | 波多野结衣在线中文字幕 | 精品免费在线视频 | 日本特黄一级片 | 久久久国产精品麻豆 | 中文字幕色网站 | 婷婷丁香六月天 | www.天天干 | 九九九九九九精品 | 欧美日韩精品在线免费观看 | 天天干天天插伊人网 | 欧美视频国产视频 | 亚洲午夜精品久久久久久久久 | 亚洲一区二区三区四区在线视频 | 缴情综合网五月天 | 一区二区三区免费网站 | 高清av中文在线字幕观看1 | 色先锋资源网 | 啪啪午夜免费 | 久久国产一区二区 | 中文字幕观看在线 | 国产欧美在线一区 | 国产在线2020 | 亚洲精品综合欧美二区变态 | 久久9视频| 伊人狠狠色丁香婷婷综合 | 国产亚洲婷婷免费 | av成人在线观看 | 97超碰精品 | 国产成人精品国内自产拍免费看 | 日韩黄色免费电影 | 国产精品美女久久久网av | 99视频免费观看 | 国产精品国产三级国产不产一地 | 国产精品欧美一区二区三区不卡 | 亚洲成人精品av | 久久精品视频免费 | 欧美va天堂va视频va在线 | 久久国产高清视频 | 国产精品精品国产色婷婷 | 在线观看你懂的网站 | 国产日韩中文字幕 | 日韩高清精品一区二区 | 99激情网| 香蕉视频在线播放 | 日韩精品视频免费看 | 午夜av不卡| 欧美日韩性生活 | 欧美日韩不卡一区 | 免费情缘 | 黄污网站在线观看 | 日韩欧美成 | 久久99精品国产99久久 | 午夜久久久久久久久久影院 | 美女久久久久久久 | 国产一区免费观看 | 久久tv视频 | japanesefreesex中国少妇 | 国产福利av在线 | 欧美一级在线看 | 亚洲综合五月天 | 成人免费视频网站 | 美女在线观看网站 | 精品国精品自拍自在线 | .国产精品成人自产拍在线观看6 | 91免费高清| 国产不卡免费视频 | 亚洲一二区视频 | 久草在线免费资源站 | 操碰av| 99精品在线播放 | 最新国产精品拍自在线播放 | 亚洲一本视频 | 九九视频一区 | 波多野结衣小视频 | 国产免费又黄又爽 | 超碰免费在线公开 | 日韩69av| 九九热在线精品 | 人人干人人模 | 在线免费观看视频a | 亚洲精品国产区 | 久久婷婷精品 | 午夜神马福利 | 超碰97.com | 久久久999精品视频 国产美女免费观看 | 婷婷五月在线视频 | 不卡精品 | 四虎永久免费在线观看 | 亚洲电影黄色 | 久久精品视频在线免费观看 | 精品在线一区二区 | 91精品专区 | 欧美二区三区91 | 1024手机在线看 | 四虎国产永久在线精品 | 国产 中文 日韩 欧美 | 草在线视频 | 玖玖视频精品 | 五月婷婷.com| 一个色综合网站 | 国产亚洲精品久久 | www国产亚洲精品久久网站 | 成人av在线亚洲 | 久久免费福利 | 超碰在线天天 | 欧美激情第十页 | 日本中文字幕电影在线免费观看 | 亚洲精品高清视频在线观看 | 国产高清视频免费在线观看 | 9ⅰ精品久久久久久久久中文字幕 | 激情综合网在线观看 | 青青河边草免费直播 | 国产精品99免视看9 国产精品毛片一区视频 | 欧美一级视频免费看 | 91黄色免费看| 欧美精品九九99久久 | 国产一级电影 | 亚洲国产97在线精品一区 | 精品国产一区二区三区久久久久久 | 午夜精品一区二区三区可下载 | 91中文字幕在线 | 欧洲精品码一区二区三区免费看 | 久久一久久 | 韩国av一区二区三区 | 久久久久久久av | 亚洲天堂网在线视频观看 | 久久狠狠一本精品综合网 | 麻豆一二三精选视频 | 成人精品电影 | 婷婷色中文字幕 | 免费日韩高清 | 欧美在线视频一区二区三区 | 久久人人97超碰国产公开结果 | 91av中文| 精品久久网| 国产精品中文字幕av | 亚洲欧美日韩精品久久奇米一区 | 国产视频不卡 | 一级黄色片在线免费观看 | 婷婷草| 国产不卡在线观看 | 探花视频在线版播放免费观看 | 很黄很污的视频网站 | 热久在线 | 久久精国产 | 国产亚洲精品久久久久久电影 | 国产精品专区在线 | 五月婷丁香 | 亚洲影院一区 | 国产99久久久国产 | 国产亚洲欧美精品久久久久久 | 91av视频在线观看免费 | av不卡中文字幕 | 精品久久久久久一区二区里番 | 亚洲高清国产视频 | 一区二区三区国产欧美 | 欧美日韩精品影院 | 日本少妇高清做爰视频 | 人人草人| 国产麻豆精品一区 | 亚洲成人中文在线 | 麻花豆传媒mv在线观看 | 亚洲视频h | 亚洲更新最快 | 亚洲成人黄色av | 亚洲精品2区| www.久久成人 | 91麻豆国产福利在线观看 | 永久免费精品视频 | 中文字幕在线观看1 | 丝袜美女视频网站 | 欧美日韩另类视频 | 特级a毛片| 三上悠亚在线免费 | 成人av片在线观看 | 免费在线播放 | 在线精品国产 | 精品久久久久久久久久久久 | 波多野结衣视频一区二区 | 国产一线二线三线性视频 | 天天色婷婷 | 亚洲精品h| 97在线观看免费观看高清 | 国产免费成人 | 国产精品2018 | 成人久久18免费 | 亚洲国产精品成人av | 国产在线a | 成人久久18免费网站 | 日韩精品中文字幕久久臀 | 美女免费黄视频网站 | 国产精品久久久亚洲 | 日本在线中文在线 | 久久免费视频在线观看6 | 中文字幕免费高清在线观看 | 久久久香蕉视频 | 免费观看高清 | 午夜少妇一区二区三区 | 久久精精品视频 | 一级性视频 | 中文在线字幕观看电影 | 欧美色综合久久 | 欧美日韩精品在线视频 | 99久久婷婷 | 午夜精品在线看 | 国产精品成人免费 | 欧美怡红院 | 免费看国产曰批40分钟 | 96国产在线 | 激情五月婷婷综合网 | 亚洲国产精品va在线看黑人 | 色婷在线 | 久久在线观看 | 亚洲日本三级 | 97视频在线观看播放 | 亚洲 欧美 综合 在线 精品 | av黄色亚洲 | 不卡av在线免费观看 | 国产手机在线观看视频 | 久久综合九色欧美综合狠狠 | 国产小视频福利在线 | 国产专区视频在线 | 综合国产在线 | 中文字幕久久精品一区 | 精品久久久久久久久亚洲 | 综合色站导航 | 国产精品久久久久一区二区三区 | 国产免码va在线观看免费 | 99国内精品久久久久久久 | 黄色特级一级片 | 日韩免费三级 | 在线播放 一区 | 亚洲精品影视 | 日韩天天综合 | 久久婷亚洲五月一区天天躁 | 欧美亚洲一区二区在线 | 天天操天天摸天天射 | 中文在线亚洲 | av观看免费在线 | 在线91av | 国产麻豆精品久久 | 亚洲精品黄色 | 日韩一区二区三区在线观看 | 91在线91拍拍在线91 | 国产91精品欧美 | 久久综合桃花 | 久久人视频 | 免费一级片在线观看 | 中文字幕精品一区久久久久 | 最新av观看 | 亚洲黄在线观看 | 99精品在线视频观看 | 日韩在线观看你懂的 | 欧美激情另类文学 | 色婷婷久久久综合中文字幕 | 涩涩色亚洲一区 | 成人午夜剧场在线观看 | 天天色天天操天天爽 | 日韩免费网址 | 少妇bbw搡bbbb搡bbbb| 亚洲欧美国产精品va在线观看 | 在线免费视频 你懂得 | 欧美激情精品久久久久久 | 西西4444www大胆艺术 | 国产一区二区三区高清播放 | 精品免费视频. | 国产在线播放一区二区三区 | 国产精品高清在线观看 | 免费亚洲精品视频 | 国产精品video爽爽爽爽 | 日本性生活一级片 | 2020天天干夜夜爽 | 久久综合久久伊人 | 五月婷香蕉久色在线看 | 91人人揉日日捏人人看 | 天天综合色天天综合 | 在线电影 一区 | 国产99在线 | 在线视频精品播放 | 欧美日韩国语 | 国产中文字幕网 | 精品免费一区 | 国产亚洲观看 | 亚洲一级二级 | 国产精品视频大全 | 欧美色888 | 正在播放国产精品 | 国产精品www | 手机av在线不卡 | 国模一二三区 | 午夜精品麻豆 | 午夜美女wwww | 久久噜噜少妇网站 | 日韩av黄 | 国色综合 | 激情综合站 | 国产原创av片| 久久久久女人精品毛片九一 | 97综合视频 | 国产综合91 | 精品极品在线 | 午夜丰满寂寞少妇精品 | 欧美在线aaa | 日韩a在线 | 国产色在线视频 | 亚洲精品福利视频 | 中字幕视频在线永久在线观看免费 | 久久永久视频 | 久久婷婷激情 | av大片网站 | 国产高清99 | 天天插天天狠天天透 | 天天干天天拍 | 视频一区二区在线 | 中文字幕在线观看91 | av线上免费观看 | 日韩精品一区二区三区电影 | 久久久午夜电影 | 国产 日韩 在线 亚洲 字幕 中文 | 欧美污污网站 | 国产精品视频地址 | 久久久99精品免费观看乱色 | 一区二区三区四区精品视频 | 久草电影免费在线观看 | 久久久久久久久久影院 | 97av在线 | 天堂av最新网址 | 亚洲自拍偷拍色图 | 久久久久看片 | 久草在线中文视频 | 天天干天天爽 | 狠狠干夜夜爽 | 天天综合网入口 | 成年人视频在线免费 | 国语对白少妇爽91 | 欧美日韩大片在线观看 | 亚洲女欲精品久久久久久久18 | 久久人人爽人人爽 | av片在线看 | 在线免费看片 | 久久试看 | 色婷婷啪啪免费在线电影观看 | 欧美在线一级片 | 国产一区在线免费 | 国产黄色片网站 | 99色在线观看| 色天天综合网 | 亚洲欧美成人在线 | 美州a亚洲一视本频v色道 | 精品久久电影 | 亚洲视频资源在线 | 天天激情综合网 | 美女国产精品 | 久久天天操 | 亚洲日本激情 | 美女视频黄在线观看 | 国产91欧美 | 精品影院一区二区久久久 | 日韩videos| 日韩大片在线观看 | 中文字幕国产一区二区 | 国产成人一区二区三区久久精品 | 99久久久成人国产精品 | 亚洲在线网址 | 日韩一区二区在线免费观看 | 国产99久久久精品 | 一 级 黄 色 片免费看的 | 国产精品久久久久久久久久东京 | 色中色资源站 | 亚洲精品视频在线免费播放 | 亚洲欧美国产精品 | 欧美日韩国产精品一区二区三区 | 91福利区一区二区三区 | 国产黄色一级片 | 一区二精品 | 国产美女精彩久久 | 992tv人人草 黄色国产区 | 在线观看亚洲a | 久久天天躁 | 久久国产精品视频免费看 | 中文字幕 二区 | 久久精品一区八戒影视 | 手机av在线不卡 | 天天操天天艹 | 亚洲视频456 | 免费看三级 | 制服丝袜欧美 | 亚洲在线成人精品 | av午夜电影| 午夜精品福利一区二区 | 国产午夜av | 91亚瑟视频 | 天天操天天干天天爱 | 91av在线视频免费观看 | 久久久www| 毛片视频网址 | 久久国产三级 | 免费看久久久 | 国产精品毛片一区视频 | 免费观看黄色av | 99久久999久久久精玫瑰 | 97夜夜澡人人爽人人免费 | 国产精品视频地址 | 久草91视频 | 夜夜操网站 | 500部大龄熟乱视频使用方法 | 婷婷伊人综合 | 国内三级在线 | 亚洲免费国产视频 | 激情伊人五月天 | 精品国产电影一区 | 91欧美精品 | 夜夜躁日日躁狠狠久久av | 在线观看黄a | 天天色综合三 | 最新一区二区三区 | 亚洲精品动漫久久久久 | 国产精品成人自拍 | 午夜影院日本 | 成 人 黄 色 片 在线播放 | 久久精品视频免费 | www.夜夜操.com| 国产精品综合久久久久 | 狂野欧美激情性xxxx | 黄色成人在线观看 | 色av资源网 | av成人在线电影 | 黄色软件大全网站 | 91人人揉日日捏人人看 | 成人在线观看av | 亚洲精品网页 | 日本中文一区二区 | 91精品视频在线观看免费 | 久久最新 | 在线观看播放av | 五月婷香蕉久色在线看 | 免费视频一区 | 在线视频第一页 | www视频免费在线观看 | 成人一级电影在线观看 | 久草视频在线免费 | 亚洲人视频在线 | 日韩理论片在线观看 | 91成人免费在线 | 久久久久久久久久久久久影院 | 久久女教师| 少妇bbw搡bbbb搡bbbb | 91精品国产网站 | 成人黄视频 | 国产精品aⅴ | 18性欧美xxxⅹ性满足 | 国产美女精品视频免费观看 | 精品国产自在精品国产精野外直播 | 中文字幕av全部资源www中文字幕在线观看 | 国产精品国产亚洲精品看不卡 | 日韩精品一区二区三区外面 | 国产资源免费在线观看 | 久久福利 | 久久a国产| 久久久久国产精品视频 | 99精品在线免费视频 | 日本中文不卡 | 亚洲欧洲一级 | 欧美 高跟鞋交 xxxxhd | 免费av的网站 | 久久久午夜剧场 | 久久久久影视 | 欧美成亚洲 | 日韩成人免费观看 | 久久精品在线免费观看 | 五月激情综合婷婷 | 99久久日韩精品免费热麻豆美女 | 亚洲九九精品 | 国产群p视频 | 中文字幕有码在线播放 | 日韩一区二区免费视频 | 九九九九九九精品 | 久久久视屏 | 久久福利综合 | 国产在线p| 国产精品毛片久久蜜 | 亚洲精品一区二区网址 | 黄色avwww | 中文字幕日本电影 | 91福利专区 | 久久影视中文字幕 | 中文字幕在线观看2018 | 99免费看片 | 色婷婷亚洲 | 深爱激情开心 | 正在播放国产一区二区 | 岛国一区在线 | 国产免费高清视频 | 国产露脸91国语对白 | 91麻豆精品国产91久久久无需广告 | 超碰在线网 | 国产精品区一区 | 亚洲视频免费在线观看 | 亚洲欧美视频一区二区三区 | a极黄色片| 久久伦理 | 国产精品成人一区二区三区吃奶 | 日韩欧美一区二区在线播放 | 97av在线视频| 亚洲人在线7777777精品 | 91九色porny在线 | 亚洲精品三级 | 中文字幕在线视频第一页 | 日韩最新理论电影 | 色综合激情久久 | 日韩免费在线观看视频 | 欧美坐爱视频 | 精品国产网址 | 中文字幕免费高清av | 久久久久久久久久久网 | 91av在线不卡 | 2023国产精品自产拍在线观看 | 久久精品伊人 | 国产精品高| 91精品区| 亚洲精品视频偷拍 | 黄色一级网 | 正在播放国产一区 | 免费性网站| 婷婷九九 | 97精品国产91久久久久久久 | 国产精品免费在线播放 | 欧美日韩高清在线 | 精品中文字幕在线播放 | 国产91免费在线观看 | 亚洲激情五月 | 欧美极品在线播放 | 日日干干| 国产成人精品a | 亚洲综合成人婷婷小说 | 日韩电影久久 | 久久久精品欧美一区二区免费 | 久久久久久高清 | 99tvdz@gmail.com| 午夜精品久久久久久久久久久久 | 五月婷婷一区 | 婷色| 久久精品高清视频 | 在线免费观看欧美日韩 | 午夜av免费观看 | 91精品久久久久 | 丝袜美女在线 | 免费精品视频在线观看 |