2. 信號槽機制 4html
3. 窗口 5node
Qwidget,QDialog,QMainwindow的異同 6linux
3.1. 模式對話框 7c++
3.3. 半模式對話框 7github
4.9. QSpinBox和QDoubleSpinBox: 18
4.13. QDateEdit和QTimeEdit:和上面同樣 21
7.6. QHttpPart和QHttpMultiPart: 47
8.1. QThread - 具備可選事件循環的低級 API 51
8.2. QThreadPool 和 QRunnable - 重用線程 52
8.3. Qt Concurrent - 使用高級 API 52
8.4. WorkerScript - QML 中的線程 53
9.1. XML(EXtendsible Markup Language Lanhuage---可擴展標記語言) 58
.Ctrl(按住)+ Tab快速切換已打開的文件
Ctrl + Shift + R,修改變量名,並應用到全部使用該變量的地方。按Alt +數字鍵(1-7)能夠快速打開對應的輸出窗口
按Ctrl + M 添加/刪除書籤,按Ctrl + . 查找並移動到下一個標籤
F2 快速切換到 光標選中對象 的源碼。
F4 在 頭文件(.h) 和 實現文件(.cpp) 之間進行切換。
Ctrl + / 註釋/取消註釋選定內容。
Ctrl + i 自動縮進選中代碼。
Ctrl + shift + up 將當前行的代碼向上移動一行。
Ctrl + shift + down 將當前行的代碼向下移動一行。
QObject::connect(btn,SIGNAL(clicked()),this.(quit()));
==(btn,「clicked()」,this,」quit()」)
SIGNAL和SLOT返回的是const chart*
一個信號能夠對應多個槽,可是槽發生的前後順序時隨機的。
(1).宏定義不能在signal和slot參數裏,signal和slot參數個數和類型必須一致。slot能夠少的參數是signal的後面的參數
(2)signal和slot不須要知道彼此的存在
QMainWindow類提供一個有菜單條、工具欄、狀態條的主應用程序窗口(例如:開發Qt經常使用的IDE-Visual Studio、Qt Creator等)。
QMainWindow擁有本身的佈局,咱們可使用QMenuBar(菜單欄)、QToolBar(工具欄)、QStatusBar(狀態欄)以及QDockWidget(懸浮窗體),佈局有一個可由任何種類小窗口所佔據的中心區域。
模式對話框有本身的事件循環,用戶必須完成這個對話框中的交互操做,而且關閉了它以後才能訪問應用程序中的其它任何窗口。他會調用exec(),當接收到信號,纔開始下一個操做。
QMainWindow *mainwindown=new QMainWindow();
mainwindown->setWindowTitle("主界面");
QDialog *pDialog = new QDialog(this);
pDialog->setWindowTitle(QStringLiteral("模式對話框"));
pDialog->show();
// 關鍵代碼
pDialog->exec();// 關閉模態對話框之後纔會執行下面的代碼
mainwindown->show();
與上面的相反,不會阻塞,能夠繼續執行主窗口。
// 關鍵代碼 pDialog->setModal(true); pDialog->show(); 取消了長時間的等待。
QLabel提供了一個文本或圖像的顯示,沒有提供用戶交互功能。
一個QLabel能夠包含如下任意內容類型:
內容 |
設置 |
純文本 |
使用setText()設置一個QString |
富文本 |
使用setText()設置一個富文本的QString |
圖像 |
使用setPixmap()設置一個圖像 |
動畫 |
使用setMovie()設置一個動畫 |
數字 |
使用setNum()設置int或double,並轉換爲純文本。 |
Nothing |
空的純文本,默認的,使用clear()設置 |
QLabel *qlabel=new QLabel();
/*
* QPixmap pixmap(":/Images/logo"); //顯示圖片 *pLabel->setPixmap(pixmap);
*/
/*
* QMovie *pMovie = new QMovie(":/Images/movie");//顯示動畫
*pLabel->setMovie(pMovie);
*pLabel->setFixedSize(135, 200);//設置大小
*pLabel->setScaledContents(true);
*pMovie->start();
*/
/*
* pLabel->setText(QString("<a href = \"%1\">%2</a>").arg("http://blog.csdn.net/liang19890820").arg(QStringLiteral("一去丶二三裏")));
*pLabel->setOpenExternalLinks(true);//容許打開連接
*/
QString strHTML = QString("<html> \
<head> \
<style> \
font{color:blue;} #f{font-size:18px; color: green;} \
</style> \
</head> \
<body>\
<font>%1</font><font id=\"f\">%2</font> \
<br/><br/> \
</body> \
</html>").arg("I am a ").arg("Qter");
qlabel->setText(strHTML);
qlabel->setAlignment(Qt::AlignCenter);
qlabel->setFixedSize(400,400);
qlabel->show();
QLineEdit是一個單行文本輸入框。
QLineEdit容許用戶輸入和編輯單行純文本,提供了不少有用的編輯功能,包括:撤消和重作、剪切和粘貼、以及拖放(見setDragEnabled())。
經過改變輸入框的echoMode(),同時也能夠設置爲一個「只寫」字段,用於輸入密碼等。
文本的長度能夠被限制爲maxLength(),可使用一個validator()或inputMask()來任意限制文本。當在同一個輸入框中切換驗證器和輸入掩碼的時候,最好是清除驗證器或輸入掩碼,防止不肯定的行爲。
信號:當文本改變時,會發射textChanged()信號。
當使用setText()改變文本時,textEdited()信號也會發射。
光標位置發生變化時,會發射cursorPositionChanged()信號
當Return或Enter鍵被按下時,發射returnPressed()信號。
當編輯完成,或者是由於輸入框失去焦點,或Return/Enter鍵被按下時,發出的editingFinished()信號。
枚舉:QLineEdit::EchoMode
描述輸入框如何顯示其內容。
常量 |
值 |
描述 |
QLineEdit::Normal |
0 |
正常顯示輸入的字符,默認選項。 |
QLineEdit::NoEcho |
1 |
不顯示任何輸入,經常使用於密碼類型,其密碼長度都須要保密的時候。 |
QLineEdit::Password |
2 |
顯示平臺相關的密碼掩碼字符,而不是實際的字符輸入。 |
QLineEdit::PasswordEchoOnEdit |
3 |
在編輯的時候顯示字符,負責顯示密碼類型。 |
經常使用接口:
QString displayText() const 或者 QString text() const 返回輸入框的當前文本,display在normal時和text()同樣,其餘顯示啥就獲得啥。
QString selectedText() const 返回選中的文本
QAction * addAction(const QIcon & icon, ActionPosition position) 添加action至指定位置。
void setEchoMode(EchoMode)輸入框顯示模式
int maxLength() const長度
void setMaxLength(int)
bool isReadOnly() const只讀
void setReadOnly()
void setSelection(int start, int length) 從位置start選擇文本爲length個字符,容許負長度。
void setValidator(const QValidator * v) 限制輸入v
Qt::Alignment alignment() const居中等
void setAlignment(Qt::Alignment flag)
QCompleter* completer() const
void setCompleter(QCompleter * c)
void deselect() 取消選中任何已選中的文本。
信號
void selectionChanged()
只要選擇改變這個信號就會被髮射。
void cursorPositionChanged(int old, int new)
只要光標移動,這個信號就會發射。前面的位置old,新的位置是new。
void editingFinished()
void returnPressed()
void textChanged(const QString & text)
void textEdited(const QString & text)
共有槽
void clear()
清除輸入框內容
void copy() const
若是echoMode()是Normal,將選中的文本複製到剪貼板。
void cut()
若是echoMode()是Normal,將所選文本複製到剪貼板並刪除它。
若是當前的驗證不容許刪除選定的文本,cut()將複製而不刪除。
void paste()
若是輸入框不是隻讀的,插入剪貼板中的文本到光標所在位置,刪除任何選定的文本。
若是最終的結果不被當前的驗證器接受,將沒有任何反應。
void redo()
重作上次操做,若是redo可用(isRedoAvailable() )。
void selectAll()
選中全部文本(即:高亮),並將光標移動到末尾。當一個默認值被插入時,這很是有用,由於若是用戶在點擊部件以前就輸入,選中的文本將被刪除。
void setText(const QString &)
設置輸入框顯示的文本。
void undo()
撤消上次操做,若是撤消可用( isUndoAvailable())。取消任何當前的選中,並更新選中到當前光標位置。
QLineEdit *pIntLineEdit = new QLineEdit(); // 整形 範圍:[1, 99]
pIntLineEdit->setPlaceholderText(QString::fromLocal8Bit("整形"));
QIntValidator *pIntValidator = new QIntValidator();
pIntValidator->setRange(1, 99);
pIntLineEdit->setValidator(pIntValidator); //控制輸入格式
QLineEdit *pValidatorLineEdit = new QLineEdit(this); // 字符和數字
pValidatorLineEdit->setPlaceholderText(QString::fromLocal8Bit("字母和數字"));
QRegExp reg("[a-zA-Z0-9]+$");
QRegExpValidator *pValidator = new QRegExpValidator(this);
pValidator->setRegExp(reg);
pValidatorLineEdit->setValidator(pValidator);
/*
*字符含義
AASCII字母字符是必須的,A-Z、a-z。
aASCII字母字符是容許的,但不是必須的。
NASCII字母字符是必須的,A-Z、a-z、0-9。
nASCII字母字符是容許的,但不是必須的。
X任何字符都是必需要的。
x任何字符都是容許的,但不是必需要的。
9ASCII數字是必需要的,0-9。
0ASCII數字是容許的,但不是必需要的。
DASCII數字是必需要的,1-9。
dASCII數字是容許的,但不是必需要的 (1-9)。
#ASCII數字或加/減符號是容許的,但不是必需要的。
H十六進制數據字符是必需要的,A-F、a-f、0-9。
h十六進制數據字符是容許的,但不是必需要的。
B二進制數據字符是必需要的,0-1。
b二進制數據字符是容許的,但不是必需要的。
>全部的字符字母都大寫
<全部的字符字母都小寫
!關閉大小寫轉換
\使用 \ 去轉義上述列出的字符。
掩碼由掩碼字符和分隔符字符串組成,後面能夠跟一個分號和用於空白的字符,空白字符在編輯後老是從文本中刪除。
*/
QLineEdit *pIPLineEdit = new QLineEdit(this);
pIPLineEdit->setInputMask("000.000.000.000;_");
QLineEdit *pPasswordLineEdit = new QLineEdit();
pPasswordLineEdit->setPlaceholderText("Password"); //輸入前的提示
pPasswordLineEdit->setEchoMode(QLineEdit::Password); //輸入的格式
能夠顯示十進制、十六進制、八進制或二進制數。
接口 |
描述 |
setDigitCount(int numDigits) |
設置所顯示的位數 |
setBinMode() |
以二進制形式顯示 |
setOctMode() |
以八進制形式顯示 |
setHexMode() |
以十六進制形式顯示 |
setDecMode() |
以十進制形式顯示(默認) |
setSmallDecimalPoint(bool) |
其參數設置爲true或者false,決定了小數點單獨站一位空間仍是在兩個位之間。換句話說,若是參數爲true,小數點將佔用比日常更少的空間 |
setSegmentStyle(SegmentStyle) |
改變現實數字的外觀,包括:Outline、Filled、Flat |
checkOverflow(double num) |
檢查給定值是否能夠在區域內顯示(也會發射overflow()信號,能夠將其鏈接到槽中處理) |
QAbstractButton提供了點擊和勾選按鈕。QRadioButton和QCheckBox類只提供了勾選按鈕,QPushButton和QToolButton提供了點擊按鈕,若是須要的話,它們還能夠提供切換行爲。
狀態:isDown()是否按下isCheced()是否選擇isEnabled()是否可被按下setToggleButton()是否切換另外一個按鈕
信號:pressed()按下release()釋放clicked()點擊toggled()狀態變化
若是繼承此類,不得不實現虛函數,paintEvent(),若是多選,放進去組裏面就好。
主要涉及setAutoDefault、setDefault、setMenu
// 設置菜單 pButton->setMenu(pMenu);
void setMenu(QMenu * menu)
設置按鈕的彈出菜單。和QPushButton用法相似
常量 |
值 |
|
Qt::NoArrow |
0 |
|
Qt::UpArrow |
1 |
|
Qt::DownArrow |
2 |
|
Qt::LeftArrow |
3 |
|
Qt::RightArrow |
4 |
|
void setPopupMode(ToolButtonPopupMode mode)
設置彈出菜單的方式,默認狀況下,設置爲DelayedPopup(延遲彈出)。
QToolButton *pButton = new QToolButton(this); pButton->setArrowType(Qt::LeftArrow); pButton->setText("Left Arrow"); // 文本位於圖標之下 pButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); pButton->setStyleSheet("QToolButton{border: none; background: rgb(68, 69, 73); color: rgb(0, 160, 230);}");
Qt::CheckState checkState() const
返回複選框的選中狀態。若是不須要三態的支持,可使用QAbstractButton::isChecked(),它返回一個布爾值。
bool isTristate() const
複選框是否爲一個三態複選框。
默認的是false,也就是說複選框只有兩個狀態。
void setCheckState(Qt::CheckState state)
設置複選框的選中狀態。若是不須要三態的支持,可使用QAbstractButton:setChecked(),它接受一個布爾值。
void setTristate(bool y = true)
設置複選框爲一個三態複選框。
void stateChanged(int state)
當複選框狀態發生改變,這個信號就會被髮射。即:用戶選中或者取消選中。
Example:// 開啓三態模式 pCheckBox->setTristate();
void MainWindow::onStateChanged(int state)
{
if (state == Qt::Checked) // "選中"
{
m_pLabel->setText("Checked");
}
else if(state == Qt::PartiallyChecked) // "半選"
{
m_pLabel->setText("PartiallyChecked");
}
else // 未選中 Qt::Unchecked
{
m_pLabel->setText("Unchecked");
}
}
QspinBox微調框
QSpinBox *pSpinBox = new QSpinBox(this);
pSpinBox->setRange(20, 200); // 範圍
pSpinBox->setSingleStep(10); // 步長
pSpinBox->setValue(150); // 當前值
pSpinBox->setPrefix("$ "); // 前綴
pSpinBox->setSuffix(" %"); // 後綴
pSpinBox->setWrapping(true); // 開啓循環
能夠子類化QSpinBox,重寫valueFromText()和textFromValue()。能夠重寫知足要求
QSlider部件提供了一個垂直或水平滑動條。
信號 |
描述 |
valueChanged() |
當滑塊的值發生了改變,發射此信號。tracking()肯定在用戶交互時,是否發出此信號。 |
sliderPressed() |
當用戶按下滑塊,發射此信號。 |
sliderMoved() |
當用戶拖動滑塊,發射此信號。 |
sliderReleased() |
當用戶釋放滑塊,發射此信號。 |
枚舉 QSlider::TickPosition
這個枚舉指定刻度線相對於滑塊和用戶操做的位置。
常量 |
值 |
描述 |
QSlider::NoTicks |
0 |
不繪製任何刻度線 |
QSlider::TicksBothSides |
3 |
在滑塊的兩側繪製刻度線 |
QSlider::TicksAbove |
1 |
在(水平)滑塊上方繪製刻度線 |
QSlider::TicksBelow |
2 |
在(水平)滑塊下方繪製刻度線 |
QSlider::TicksLeft |
TicksAbove |
在(垂直)滑塊左側繪製刻度線 |
QSlider::TicksRight |
TicksBelow |
在(垂直)滑塊右側繪製刻度線 |
int nMin = 0;
int nMax = 200;
int nSingleStep = 10;
QSpinBox *pSpinBox = new QSpinBox(this); // 微調框
pSpinBox->setMinimum(nMin); // 最小值
pSpinBox->setMaximum(nMax); // 最大值
pSpinBox->setSingleStep(nSingleStep); // 步長
QSlider *pSlider = new QSlider(this); // 滑動條
pSlider->setOrientation(Qt::Horizontal); // 水平方向
pSlider->setMinimum(nMin); // 最小值
pSlider->setMaximum(nMax); // 最大值
pSlider->setSingleStep(nSingleStep); // 步長
// 鏈接信號槽(相互改變)
connect(pSpinBox, SIGNAL(valueChanged(int)), pSlider, SLOT(setValue(int)));
connect(pSlider, SIGNAL(valueChanged(int)), pSpinBox, SLOT(setValue(int)));
pSpinBox->setValue(10);
pProgressBar2->setInvertedAppearance(true); // 反方向
QProgressBar *pProgressBar = new QProgressBar(this);
pProgressBar->setOrientation(Qt::Horizontal); // 水平方向
pProgressBar->setMinimum(0); // 最小值
pProgressBar->setMaximum(4800); // 最大值
pProgressBar->setValue(2000); // 當前進度
double dProgress = (pProgressBar->value() - pProgressBar->minimum()) * 100.0
/ (pProgressBar->maximum() - pProgressBar->minimum());
pProgressBar->setFormat(QString::fromLocal8Bit("當前進度爲:%1%").arg(QString::number(dProgress, 'f', 1)));
pProgressBar->setAlignment(Qt::AlignRight | Qt::AlignVCenter); // 對齊方式
提供了一個部件,用於編輯日期和時間。
QDateTimeEdit *dateTimeEdit = new QDateTimeEdit(this); QDateTimeEdit *dateTimeEdit2 = new QDateTimeEdit(QDateTime::currentDateTime(), this); QDateTimeEdit *dateEdit = new QDateTimeEdit(QDate::currentDate(), this); QDateTimeEdit *timeEdit = new QDateTimeEdit(QTime::currentTime(), this);
能夠設置日期格式
// 設置日期時間格式
dateTimeEdit->setDisplayFormat("yyyy-MM-dd HH:mm:ss"); dateTimeEdit2->setDisplayFormat("yyyy/MM/dd HH-mm-ss"); dateEdit->setDisplayFormat("yyyy.M.d"); timeEdit->setDisplayFormat("H:mm");
dateEdit->setMinimumDate(QDate::currentDate().addDays(-365)); // -365天 dateEdit->setMaximumDate(QDate::currentDate().addDays(365)); // +365天
setCalendarPopup(true)//顯示日曆
信號:dateChanged()、dateTimeChanged()、timeChanged(),當日期、日期時間、時間改變時發射。
提供了一個滾動視圖到另外一個部件
QLabel *imageLabel = new QLabel(this);
QPixmap pixmap(":/Images/head");
pixmap = pixmap.scaled(200, 200, Qt::KeepAspectRatio); // 圖片縮放
imageLabel->setPixmap(pixmap);
imageLabel->setStyleSheet("background: white;"); // 標籤白色背景
imageLabel->setAlignment(Qt::AlignCenter); // 圖片居中
QScrollArea *scrollArea = new QScrollArea(this);
scrollArea->setBackgroundRole(QPalette::Dark); // 背景色
scrollArea->setWidget(imageLabel);
scrollArea->setAlignment(Qt::AlignCenter); // 居中對齊
scrollArea->setWidgetResizable(true); // 自動調整大小
scrollArea->setWidget(imageLabel);
QWidget *widget = scrollArea->widget();//獲取部件
QWidget *widget = scrollArea->takeWidget();//一移除部件
QLabel *pLabel = qobject_cast<QLabel *>(widget);
提供了一個列(選項卡式的)部件條目
每一個item都有一個itemText()、一個可選的itemIcon()、一個可選的itemToolTip()、和一個widget()函數 。item的屬性能夠經過setItemText()、setItemIcon()、和setItemToolTip()來改變,而且每一個item能夠經過setItemEnabled()單獨設置爲是否可用。
Item的添加使用addItem(),或經過insertItem()在特定位置插入。若是要獲取items的總數,能夠調用count()函數。Item可使用removeItem()從toolbox中刪除。結合removeItem()和insertItem(),容許你將item移動到不一樣的位置。
當前item部件的索引由currentIndex()返回,並使用setCurrentIndex()來設置。一個特定item的索引可使用indexOf()來獲取,item()則返回給定索引的item。
當前的item發生變化時,會發射currentChanged()信號。
爲應用程序在系統托盤中提供一個圖標
要檢查系統托盤是否存在在用戶的桌面上,調用QSystemTrayIcon::isSystemTrayAvailable()靜態函數。
void hide() 隱藏系統托盤。
void setVisible(bool visible) 設置系統托盤是否可見。
設置爲true或調用show()使系統托盤圖標可見;設置爲false或調用hide()隱藏它。
void show() 顯示系統托盤。
void showMessage(const QString & title, const QString & message, QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::Information, int millisecondsTimeoutHint = 10000)
顯示一個氣球消息,使用所給出的標題、消息、圖標和指定的時間,標題和消息必須是純文本字符串。
消息能夠被用戶點擊,當用戶點擊時發出messageClicked()信號 。
信號:
void activated(QSystemTrayIcon::ActivationReason reason)
當用戶激活系統托盤圖標,這個信號被髮射。reason指定激活的緣由, QSystemTrayIcon::ActivationReason列舉了各類緣由。
void messageClicked()
當使用showMessage()顯示的消息被用戶點擊時,此信號被髮射。
QSystemTrayIcon *pSystemTray = new QSystemTrayIcon(this); TrayMenu *pTrayMenu = new TrayMenu(this); // 設置系統托盤的上下文菜單 pSystemTray->setContextMenu(pTrayMenu); // 設置系統托盤提示信息、托盤圖標 pSystemTray->setToolTip(QString::fromLocal8Bit("我就是托盤")); pSystemTray->setIcon(QIcon(":/icon/login")); // 鏈接信號槽 connect(pTrayMenu, SIGNAL(showWindow()), this, SLOT(showWindow())); connect(pSystemTray , SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(onActivated(QSystemTrayIcon::ActivationReason))); // 顯示系統托盤 pSystemTray->show(); // 顯示系統托盤提示信息 pSystemTray->showMessage(QString::fromLocal8Bit("托盤標題"), QString::fromLocal8Bit("托盤顯示內容"));
// 記住密碼 第2行,第1列開始,佔1行1列 水平居左 垂直居中 pLayout->addWidget(pRememberCheckBox, 2, 1, 1, 1, Qt::AlignLeft | Qt::AlignVCenter);
pLayout->setHorizontalSpacing(10); // 設置水平間距pLayout->setVerticalSpacing(10); // 設置垂直間距 pLayout->setContentsMargins(10, 10, 10, 10);// 設置外間距
pImageLabel->setScaledContents(true);//圖片只適應大小
setRowMinimumHeight(int row, int minSize) 設置行最小高度
setColumnMinimumWidth(int column, int minSize) 設置列最小寬度
columnCount()獲取列數
rowCount() 獲取行數
setOriginCorner(Qt::Corner)設置原始方向
setRowStretch(int row, int stretch)
setColumnStretch(int column, int stretch)設置行/列的伸縮空間
QBoxlayout:
pHLayout->addStretch(); // 添加伸縮,在左邊添加,這樣就會居右顯示,可居中,均分,居左
pHLayout->setMargin(100);//外邊距100
pHLayout->setSpacing(100);//間距
pHLayout->setStretchFactor(two, 2);//拉伸係數
pHLayout->setDirection(QBoxLayout::RightToLeft);//佈局方向
pHLayout->setContentsMargins(50,20,20,20);//widget之間左上右下的邊距
QStackedLayout:
類提供了多頁面切換的佈局,一次只能看到一個界面。
QPushButton *pButton = new QPushButton(this);
QLabel *pFirstPage= new QLabel(this);
QLabel *pSecondPage = new QLabel(this);
QLabel *pThirdPage = new QLabel(this);
m_pStackedLayout = new QStackedLayout();
pButton->setText(QStringLiteral("點擊切換"));
pFirstPage->setText(QStringLiteral("一去丶二三裏"));
pSecondPage->setText(QStringLiteral("青春不老,奮鬥不止!"));
pThirdPage->setText(QStringLiteral("純正開源之美,有趣、好玩、靠譜。。。"));
// 添加頁面(用於切換)
m_pStackedLayout->addWidget(pFirstPage);
m_pStackedLayout->addWidget(pSecondPage);
m_pStackedLayout->addWidget(pThirdPage);
QVBoxLayout *pLayout = new QVBoxLayout();
pLayout->addWidget(pButton, 0, Qt::AlignLeft | Qt::AlignVCenter);
pLayout->addLayout(m_pStackedLayout);
pLayout->setSpacing(10);
pLayout->setContentsMargins(10, 10, 10, 10);
setLayout(pLayout);
// 鏈接切換按鈕信號與槽
connect(pButton, &QPushButton::clicked, this, &MainWindow::switchPage);
// 切換頁面
void MainWindow::switchPage()
{
int nCount = m_pStackedLayout->count();
int nIndex = m_pStackedLayout->currentIndex();
// 獲取下一個須要顯示的頁面索引
++nIndex;
// 當須要顯示的頁面索引大於等於總頁面時,切換至首頁
if (nIndex >= nCount)
nIndex = 0;
m_pStackedLayout->setCurrentIndex(nIndex);
}
手動佈局:
void MainWindow::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
int nSpacing = 10;
int nLeft = 10;
int nTop = 10;
int nRight = 10;
int nBottom = 10;
// 標籤位置、大小
m_pLabel->setGeometry(nLeft, nTop, width() - nLeft - nRight, 20);
// 按鈕大小
m_pButton->setFixedSize(75, 25);
// 設置按鈕位置
m_pButton->move(width() - m_pButton->width() - nRight, height() - nBottom - m_pButton->height());
// 中央窗體位置、大小
m_pCentralWidget->setGeometry(nLeft, nTop + nSpacing + m_pLabel->height(),
width() - nLeft - nRight, height() - nTop - 2 *nSpacing - m_pLabel->height() - m_pButton->height() - nBottom);
提供監視文件和目錄修改的接口
公共函數:
bool addPath(const QString & path) 存在則添加監控
QStringList addPaths(const QStringList & paths) 返回值是不能添加的列表
QStringList directories() const返回被監控目錄的路徑列表
QStringList files() const返回被監控文件的路徑列表
bool removePath(const QString & path) 移除指定路徑
QStringList removePaths(const QStringList & paths)
信號:
void directoryChanged(const QString & path) 目錄被修改觸發
void fileChanged(const QString & path) 文件被修改
提供的函數用於訪問常見的桌面服務。如用chorme打開www.baidu.com
靜態共有函數:
bool openUrl(const QUrl & url);
QDesktopServices::openUrl(QUrl("http://www.baidu.com"));
QDesktopServices::openUrl(QUrl("file:///D:/Program Files/Youdao"));
void setUrlHandler(const QString & scheme, QObject * receiver, const char * method)這個函數提供了一種方法來定製openUrl()行爲。若是以指定的scheme調用openUrl()(帶參數URL),接受者指定的函數將被調用來代替QDesktopServices啓動外部應用程序。
提供了重複和單次觸發信號的定時器。
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1000);
QTimer::singleShot(200, this, SLOT(updateCaption()));//單次執行
精度:枚舉Qt::TimerType:
常量 |
值 |
描述 |
Qt::PreciseTimer |
0 |
精確的定時器,儘可能保持毫秒精度。 |
Qt::CoarseTimer |
1 |
粗略的定時器,儘可能保持精度在所需的時間間隔5%範圍內。 |
Qt::VeryCoarseTimer |
2 |
很粗略的定時器,只保留完整的第二精度。 |
成員函數:
bool isActive() const 若是定時器正在運行,返回true,不然返回false。
int remainingTime() const返回定時器的剩餘時間(毫秒爲單位),直到超時。若是定時器不活躍,返回值是-1。若是定時器過時,返回值爲0。
void setInterval(int msec) 設置超時間隔(毫秒爲單位)。
默認值是0,這時,一旦窗口系統事件隊列中的全部事件都已經被處理完,一個時間間隔爲0的QTimer就會觸發。
void setSingleShot(bool singleShot) 設置定時器是否爲單次觸發。
單次觸發定時器只觸發一次,非單次的話,則每過一個時間間隔都會觸發。
void setTimerType(Qt::TimerType atype)
設置定時器的準確性。默認值是Qt::CoarseTimer。
int timerId() const 若是定時器正在運行,返回定時器的ID,不然返回-1。
void start(int msec) 啓動或從新啓動一個超時時間間隔爲毫秒的定時器。
若是定時器正在運行,它將被中止和從新啓動。若是singleShot爲true,定時器將只激活一次。
void start() 同上,重載了start()。
void stop() 中止定時器。
信號:
void timeout() 定時器超時後,這個信號被髮射。
注意:這是一個私有的信號。它能夠在信號鏈接使用,但不能由用戶發出。
爲QDirModel和QFileSystemModel類提供了文件圖標。
枚舉QFileIconProvider::IconType:
常量 |
值 |
QFileIconProvider::Computer |
0 |
QFileIconProvider::Desktop |
1 |
QFileIconProvider::Trashcan |
2 |
QFileIconProvider::Network |
3 |
QFileIconProvider::Drive |
4 |
QFileIconProvider::Folder |
5 |
QFileIconProvider::File |
6 |
公共函數:
QIcon icon(IconType type) const 獲取IconType圖標類型對應的圖標。
QIcon icon(const QFileInfo & info) const 獲取QFileInfo文件信息對應的圖標。
Options options() const 獲取全部影響QFileIconProvider的選項。默認狀況下,全部選項被禁用。
void QFileIconProvider::setOptions(Options options) 設置全部影響QFileIconProvider的選項。
QString type(const QFileInfo & info) const 獲取QFileInfo文件信息對應的類型描述。
QListWidget *pListWidget = new QListWidget(this);
pListWidget->setIconSize(QSize(48, 48)); // 設置單元項圖片大小
pListWidget->setResizeMode(QListView::Adjust); // 設置大小模式-可調節
pListWidget->setViewMode(QListView::IconMode); // 設置顯示模式
pListWidget->setMovement(QListView::Static); // 設置單元項不可被拖動
pListWidget->setSpacing(10); // 設置單元項間距
for (int i = 0; i <= 6; ++i)
{
// 獲取圖標
QFileIconProvider provider;
QIcon icon = provider.icon((QFileIconProvider::IconType)i);
// 添加單元項
QListWidgetItem *pItem = new QListWidgetItem(pListWidget);
pItem->setIcon(icon);
pListWidget->addItem(pItem);
}
QListWidget *pListWidget = new QListWidget(this);
pListWidget->resize(500,500);
QStringList strList;
strList << QString::fromLocal8Bit("新建文件夾");
QFileInfo info;
info.setFile(QString("/home/zz/qt/%1").arg(strList.at(0)));
QFileeIconProvider provider;
QIcon icon = provider.icon(info);
QString strType = provider.type(info);
QListWidgetItem *pItem = new QListWidgetItem(pListWidget);
pItem->setIcon(icon);
pItem->setText(strType);
pListWidget->addItem(pItem);
臨時文件放在臨時文件夾,不能夠指定去命名,由系統自動分配一個惟一的名字。QTemporaryFile file;
if (file.open()) {
// file.fileName() 返回惟一的文件名
}
// QTemporaryFile析構,移除臨時文件
經常使用接口:
void setAutoRemove(bool b)
設置是否爲自動刪除模式。默認狀況下,自動刪除模式打開。
bool open()
QTemporaryFile在QIODevice::ReadWrite(讀寫)模式下老是打開的,這方便訪問文件中的數據。成功時返回true,將設置fileName()爲惟一的文件名。
void setFileTemplate(const QString & name)
設置文件模板。默認文件模板爲qcoreappname.XXXXXX,被放置在QDir::tempPath()目錄中。
virtual QString fileName() const
從新實現QFileDevice::fileName()獲取完整的惟一文件名。在QTemporaryFile打開以前,返回值爲空,以後將包含fileTemplate(),加上其它的字符使其惟一。
QTemporaryFile * createNativeFile(QFile & file)
建立本地臨時文件若是文件不是本地文件,使用QDir::tempPath()建立一個QTemporaryFile,將文件的內容複製給它。若是文件是一個本地文件,返回0,什麼都不作。
QApplication a(argc, argv);
// 設置模板名稱
QString strFileName = QDir::tempPath() + QDir::separator() +
QCoreApplication::applicationName() + "_XXXXXX." + "docx";
QTemporaryFile tmpFile(strFileName);
// 設置爲不自動刪除
tmpFile.setAutoRemove(false);
qDebug() << "tempPath : " << QDir::tempPath();
if (tmpFile.open())
{
tmpFile.close();
QString strFileTemplate = tmpFile.fileTemplate();
QString strFileName = tmpFile.fileName();
qDebug() << "fileTemplate : " << strFileTemplate;
qDebug() << "fileName : " << strFileName;
// tmpFile.remove();能夠手動刪除
}
else
{
qCritical() << "failed to write temporary file";
}
供了生成密碼散列的方法。該類能夠用於生成二進制或文本數據的加密散列值。目前支持MD四、MD五、SHA-一、SHA-22四、SHA-25六、SHA-384和SHA-512。
枚舉QCryptographicHash::Algorithm:
常量 |
取值 |
描述 |
QCryptographicHash::Md4 |
0 |
生成一個MD4散列 |
QCryptographicHash::Md5 |
1 |
生成一個MD5散列 |
QCryptographicHash::Sha1 |
2 |
生成一個SHA-1散列 |
QCryptographicHash::Sha224 |
3 |
生成一個SHA-224散列(SHA-2) |
QCryptographicHash::Sha256 |
4 |
生成一個SHA-256散列(SHA-2) |
QCryptographicHash::Sha384 |
5 |
生成一個SHA-384散列(SHA-2) |
QCryptographicHash::Sha512 |
6 |
生成一個SHA-512散列(SHA-2) |
QCryptographicHash::Sha3_224 |
7 |
生成一個SHA3-224散列 |
QCryptographicHash::Sha3_256 |
8 |
生成一個SHA3-256散列 |
QCryptographicHash::Sha3_384 |
9 |
生成一個SHA3-384散列 |
QCryptographicHash::Sha3_512 |
10 |
生成一個SHA3-512散列 |
·
void addData(const char * data, int length)
將第一個字符長度的數據添加到密碼散列。
bool addData(QIODevice * device)
從開放的QIODevice設備讀取數據,直到結束並計算出哈希值。若是成功讀取,返回true。
void addData(const QByteArray & data)
這個函數重載了addData()。
void reset()
重置對象。
QByteArray result() const
獲取最終的哈希值。
QByteArray hash(const QByteArray & data, Algorithm method)
獲取data數據的哈希值。
QByteArray hash = QCryptographicHash::hash("i love you", QCryptographicHash::Md5);
qDebug()<<hash.toHex();
QCryptographicHash hash(QCryptographicHash::Md5);
hash.addData("始於顏值,敬於才華,合於性格,久於善良,終於人品"); // 添加數據到加密哈希值
qDebug()<<hash.result().toHex();
類 |
描述 |
QAbstractNetworkCache |
爲緩存實現的接口 |
QAbstractSocket |
包含全部 socket 類型的基礎功能 |
QAuthenticator |
認證對象 |
QDnsDomainNameRecord |
存儲關於域名記錄的信息 |
QDnsHostAddressRecord |
存儲關於主機地址記錄的信息 |
QDnsLookup |
表示一個DNS查詢 |
QDnsMailExchangeRecord |
存儲有關 DNS MX 記錄的信息 |
QDnsServiceRecord |
存儲有關 DNS SRV 記錄的信息 |
QDnsTextRecord |
存儲有關 DNS TXT 記錄的信息 |
QHostAddress |
IP地址 |
QHostInfo |
主機名查詢靜態函數 |
QHttpMultiPart |
相似於一個 MIME 多個部分消息,經過HTTP發送 |
QHttpPart |
持有一個 body 部分,用於 HTTP 多個部分的 MINE 消息 |
QLocalServer |
本地 socket 依賴的 server |
QLocalSocket |
本地 socket |
QNetworkAccessManager |
容許程序發送網絡請求和接收響應 |
QNetworkAddressEntry |
存儲一個 IP 地址,經過網絡接口的支持,連同相關的網絡掩碼和廣播地址 |
QNetworkCacheMetaData |
緩存信息 |
QNetworkConfiguration |
一個或多個配置接入點的抽象概念 |
QNetworkConfigurationManager |
管理由系統提供的網絡配置 |
QNetworkCookie |
管理由系統提供的網絡配置 |
QNetworkCookieJar |
實現 QNetworkCookie 對象的一個簡單jar |
QNetworkDiskCache |
很是基本的磁盤緩存 |
QNetworkInterface |
主機的IP地址和網絡接口列表 |
QNetworkProxy |
網絡層代理 |
QNetworkProxyFactory |
精細的代理選擇 |
QNetworkProxyQuery |
用於查詢一個 socket 的代理設置 |
QNetworkReply |
包含 QNetworkAccessManager 發送的請求數據和消息頭 |
QNetworkRequest |
持有一個 QNetworkAccessManager 發送的請求 |
QNetworkSession |
控制系統的接入點並啓用例的會話管理,爲了當多個客戶端訪問相同的接入點 |
QSslCertificate |
用於 X509 證書的方便 API |
QSslCertificateExtension |
用於訪問 X509 證書擴展的API |
QSslCipher |
表明一個SSL加密密碼 |
QSslConfiguration |
持有 SSL 鏈接的配置及狀態 |
QSslEllipticCurve |
表明了一種橢圓曲線使用橢圓曲線密碼算法 |
QSslError |
SSL 錯誤 |
QSslKey |
私鑰和公鑰的接口 |
QSslPreSharedKeyAuthenticator |
預共享密鑰認證數據(PSK)密碼套件 |
QSslSocket |
clients 和 servers 的 SSL 加密 socket |
QTcpServer |
基於 TCP 的 server |
QTcpSocket |
TCP socket |
QUdpSocket |
UDP socket |
·
QT += network
#include <QtNetwork>
int main(int argc, char *argv[])
{
QApplication a(argc,argv);
Form w;
w.show();
QHostInfo infolocal=QHostInfo::fromName(QHostInfo::localHostName());
w.ui->textBrowser->append(QHostInfo::localHostName());
foreach (QHostAddress str, infolocal.addresses())
{
w.ui->textBrowser->append(str.toString());
}
QHostInfo info=QHostInfo::fromName("www.baidu.com");
w.ui->textBrowser->append(info.hostName());
foreach (QHostAddress str, info.addresses())
{
w.ui->textBrowser->append(str.toString());
}
return a.exec();
}
QHostAddress add=QHostAddress(QHostAddress::AnyIPv6);
QList<QHostAddress> list = QNetworkInterface::allAddresses();
foreach (QHostAddress address, list)
{
if (address.isNull())
continue;
w.ui->textBrowser->append( "********************");
QAbstractSocket::NetworkLayerProtocol nProtocol = address.protocol();
QString strScopeId = address.scopeId();
QString strAddress = address.toString();
bool bLoopback = address.isLoopback();
// 若是是IPv4
if (nProtocol == QAbstractSocket::IPv4Protocol) {
bool bOk = false;
quint32 nIPV4 = address.toIPv4Address();
if (bOk)
w.ui->textBrowser->append("IPV4 : "+ nIPV4);
}
// 若是是IPv6
else if (nProtocol == QAbstractSocket::IPv6Protocol) {
QStringList IPV6List("");
Q_IPV6ADDR IPV6 = address.toIPv6Address();
for (int i = 0; i < 16; ++i) {
quint8 nC = IPV6[i];
IPV6List << QString::number(nC);
}
w.ui->textBrowser->append( "IPV6 : " +IPV6List.join(" "));
}
w.ui->textBrowser->append( "Protocol : " + nProtocol);
w.ui->textBrowser->append( "ScopeId : " + strScopeId);
w.ui->textBrowser->append( "Address : " + strAddress);
w.ui->textBrowser->append("IsLoopback : "+ bLoopback);
}
由網絡接口支持,存儲了一個IP地址,子網掩碼和廣播地址。
經常使用接口:
QHostAddress broadcast() const
QHostAddress ip() const
QHostAddress netmask() const
QHostAddress netmask() const返回前綴長度,ipv4返回0-32,ipv6返回0-128
QList<QNetworkInterface> list = QNetworkInterface::allInterfaces();
foreach (QNetworkInterface netInterface, list) {
QList<QNetworkAddressEntry> entryList = netInterface.addressEntries();
foreach(QNetworkAddressEntry entry, entryList) { // 遍歷每個IP地址
qDebug() << "********************";
qDebug()<<"Name:"<<netInterface.name();
qDebug()<<"HardwareAddress:"<<netInterface.hardwareAddress();
qDebug() << "IP Address:" << entry.ip().toString(); // IP地址
qDebug() << "Netmask:" << entry.netmask().toString(); // 子網掩碼
qDebug() << "Broadcast:" << entry.broadcast().toString(); // 廣播地址
qDebug() << "Prefix Length:" << entry.prefixLength(); // 前綴長度
}
}
提供了一種方法來操縱 URL 查詢中的 key-value 對。
Url的構造:
QString baseUrl = "http://www.zhihu.com/search?";
QByteArray bytes;
bytes.append("type=content&");
bytes.append(QString("q=%1").arg("Qt")); // Qt 做爲變量輸入
baseUrl += bytes;
QUrl url(baseUrl);
qDebug() << url;
QString baseUrl = "http://www.zhihu.com/search";
QUrl url(baseUrl);
QUrlQuery query;
query.addQueryItem("type", "content");
query.addQueryItem("q", "Qt");
url.setQuery(query);
qDebug() << url;
QString baseUrl = "http://www.zhihu.com/search";
QUrl url(baseUrl);
QUrlQuery query;
query.setQuery("type=content&q=Qt");
url.setQuery(query);
qDebug() << url;
提供了一個方便的接口使用 URLs
構造:
QUrl url("https://github.com/");
url.setUrl("www.guet.edu.cn");
也能夠逐漸地構造 URL,經過調用 setScheme()、setUserName()、setPassword()、setHost()、setPort()、setPath()、setQuery() 和 setFragment()。一些方便的函數也可供使用:setAuthority() 設置用戶名、密碼、主機和端口。setUserInfo() 設置用戶名和密碼。
深刻使用:
相對路徑
QUrl baseUrl("http://qt.digia.com/Support/");
QUrl relativeUrl("../Product/Library/");
qDebug(baseUrl.resolved(relativeUrl).toString()); // 打印 "http://qt.digia.com/Product/Library/"
常量 |
值 |
描述 |
QHttpMultiPart::MixedType |
0 |
對應於 "multipart/mixed" 子類型,意味着 body 部位是相互獨立的。如 RFC 2046 所述。 |
QHttpMultiPart::RelatedType |
1 |
對應於 "multipart/related" 子類型,意味着 body 部位是相互關聯的。如 RFC 2387 所述。 |
QHttpMultiPart::FormDataType |
2 |
對應 "multipart/form-data" 子類型,意味着 body 部位包含表單元素。如 RFC 2388 所述。 |
QHttpMultiPart::AlternativeType |
3 |
對應 "multipart/alternative" 子類型,意味着 body 部位是相同信息的替表明示。如 RFC 2046 所述。 |
一個httppart有一個body,這個body由header和數據塊組成
例子:
Content-Type: text/plain
Content-Disposition: form-data; name="text"
here goes the body
構建httppart
QHttpPart textPart;
textPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain")); textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"text\"")); textPart.setBody("here goes the body");
QHttpPart imagePart;
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image\""));
imagePart.setRawHeader("Content-ID", "my@content.id"); // 添加任何你喜歡的 headers
QFile *file = new QFile("image.jpg");
file->open(QIODevice::ReadOnly);
imagePart.setBodyDevice(file);
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart textPart;
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"text\""));
textPart.setBody("my text");
QHttpPart imagePart;
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image\""));
QFile *file = new QFile("image.jpg");
file->open(QIODevice::ReadOnly);
imagePart.setBodyDevice(file);
file->setParent(multiPart); // 如今不能刪除文件,因此用 multiPart 刪除
multiPart->append(textPart);
multiPart->append(imagePart);
QUrl url("http://my.server.tld");
QNetworkRequest request(url);
QNetworkAccessManager manager;
QNetworkReply *reply = manager.post(request, multiPart);
multiPart->setParent(reply); // 用 reply 刪除 multiPart
// 這裏鏈接信號等
在進行網絡請求以前,首先,要查看 QNetworkAccessManager 支持的協議
qDebug()<<manager->supportedSchemes();
QNetworkRequest、QNetworkReply 和 QNetworkAccessManager,使用常見的協議執行網絡操做。
// URL
QString baseUrl = "http://www.csdn.net/";
// 構造請求
QNetworkRequest request;
request.setUrl(QUrl(baseUrl));
// 發送請求
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkReply *pReplay = manager->get(request);
// 開啓一個局部的事件循環,等待響應結束,退出
QEventLoop eventLoop;
QObject::connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit);
eventLoop.exec();
// 獲取響應信息
QByteArray bytes = pReplay->readAll();
qDebug() << bytes;
HTTPS登陸:
http文件下載:
進程間通訊:
事件
何爲線程:簡單的說就是兩個相同的程序,並行的執行不一樣的任務,進程則是兩個不一樣的程序,在用進程時注意對相同數據操做時候的數據保護,QMUtex是強制數據保護的基本類,QReadWriteLock區分了讀和寫的訪問。QSemaphore 是 QMutex 的一個推廣,能夠保護必定數量相同的資源。相比之下,一個 QMutex 只能保護一個資源。QWaitCondition 同步線程,不經過執行互斥,而經過提供一個條件變量。其它原語使線程等待,直到資源被解鎖;QWaitCondition 使線程等待,直到知足一個特定的條件。讓等待中的線程繼續進行,調用 wakeOne() 來喚醒一個隨機選擇的線程或 wakeAll() 同時喚醒全部。顯示瞭如何使用 QWaitCondition 代替 QSemaphore 來實現「生產者 - 消費者」模式。
可重入和線程安全:好比一個類定義了一個整數變量和相關操做函數,由於c++的類每每是可重入的,他們操做本身的數據,固然能夠重入。可是一個對象執行多個線程時,數據每每會發生混亂。這每每是不安全的。
QThread 是 Qt 中全部線程控制的基礎,每一個 QThread 實例表示和控制一個線程。
QThread 能夠直接實例化或子類,實例化 QThread 提供了一個並行事件循環,容許在次線程中調用 QObject 的槽函數。子類化 QThread 容許應用程序在開始其事件循環以前初始化新的線程,或者運行沒有事件循環的並行代碼。
有關如何使用 QThread 的演示,請參閱 QThread 類參考和線程示例。
常常建立和銷燬線程多是昂貴的,爲了減小這種開銷,現有線程能夠從新用於新任務。QThreadPool 是可重用的 QThreads 的集合。
要在 QThreadPool 的線程中運行代碼,請從新實現 QRunnable::run() 並實例化子類化的 QRunnable。使用 QThreadPool::start() 將 QRunnable 放在 QThreadPool 的運行隊列中。當線程可用時,QRunnable::run() 中的代碼將在該線程中執行。
每一個 Qt 應用程序有一個全局線程池,可經過 QThreadPool::globalInstance() 進行訪問。此全局線程池根據 CPU 中的核數自動維護最佳線程數。可是,能夠顯式建立和管理單獨的 QThreadPool。
Qt Concurrent 模塊提供了處理一些常見並行計算模式的高級函數:map、filter 和 reduce。與使用 QThread 和 QRunnable 不一樣,這些函數不須要使用低級線程原語,例如:互斥鎖或信號量。相反,他們返回一個 QFuture 對象,當他們準備就緒時,可用於檢索函數的結果。QFuture 也能夠用於查詢計算進度並暫停/恢復/取消計算。爲方便起見,QFutureWatcher 經過信號和槽與 QFutures 進行交互。
Qt Concurrent 的 map、filter 和 reduce 算法在全部可用的處理器核心之間自動分配計算,所以今天編寫的應用程序將在之後在具備更多核心的系統上部署時繼續擴展。
這個模塊還提供了 QtConcurrent::run() 函數,它能夠在另外一個線程中運行任何函數。可是,QtConcurrent::run() 只支持可用於 map、filter 和 reduce 函數的一個子集。QFuture 能夠用於檢索函數的返回值,並檢查線程是否正在運行。可是,對 QtConcurrent::run() 的調用僅使用一個線程,不能被暫停/恢復/取消,而且不能被查詢進度。
有關各個功能的詳細信息,請參閱 Qt Concurrent 模塊文檔。
WorkerScript QML 類型容許 JavaScript 代碼與 GUI 線程並行運行。
每一個 WorkerScript 實例能夠有一個 .js 腳本附加到它。當調用 WorkerScript::sendMessage() 時,腳本將在單獨的線程(和單獨的 QML 上下文)中運行。當腳本完成運行時,它能夠發送一個回覆給 GUI 線程,它將調用 WorkerScript::onMessage() 信號處理程序。
使用 WorkerScript 相似於使用已移動到另外一個線程的工做 QObject。 數據經過信號在線程之間傳輸。
Concurrent:
QtConcurrent::map():將一個函數應用於一個容器中的每一項,就地修改 items。
QtConcurrent::mapped():和 map() 相似,只是它返回一個包含修改內容的新容器。
QtConcurrent::mappedReduced():和 mapped() 相似,只是修改後的結果減小或組合成一個單一的結果。
QtConcurrent::filter():從一個容器中刪除全部 items,基於一個 filter 函數的結果。
QtConcurrent::filtered():和 filter() 相似,只是它返回一個包含過濾內容的新容器。
QtConcurrent::filteredReduced():和 filtered() 相似,只是過濾後的結果減小或組合成一個單一的結果。
QtConcurrent::run():在另外一個線程中運行一個函數。
QFuture:表示異步計算的結果
QFutureIterator:容許經過 QFuture 遍歷可用的結果
QFutureWatcher:容許使用信號槽來監控一個 QFuture
QFutureSynchronizer:是一個方便的類,用於一些 QFutures 的自動同步
啓動:
void start(Priority priority = InheritPriority) 啓動函數,調用時會執行run()函數,可是run()會發射started()信號,若是線程在運行,則無反應
執行:
void exec()進入事件循環並等待直到調用exit(),返回值是經過調用exit()來得到,若是調用成功則範圍0
退出:
void quit() [slot] 告訴線程事件循環退出,返回0表示成功,至關於調用了QThread::exit(0)。void exit(int returnCode = 0)告訴線程事件循環退出。 調用這個函數後,線程離開事件循環後返回,QEventLoop::exec()返回returnCode,按照慣例,0表示成功;任何非0值表示失敗。
void requestInterruption() 請求線程的中斷。該請求是諮詢意見而且取決於線程上運行的代碼,來決定是否及如何執行這樣的請求。此函數不中止線程上運行的任何事件循環,而且在任何狀況下都不會終止它。
等待:
void requestInterruption() 請求線程的中斷。該請求是諮詢意見而且取決於線程上運行的代碼,來決定是否及如何執行這樣的請求。此函數不中止線程上運行的任何事件循環,而且在任何狀況下都不會終止它。
void sleep(unsigned long secs) [static]
強制當前線程睡眠secs秒
void usleep(unsigned long usecs) [static] 強制當前線程睡眠usecs微秒
bool wait(unsigned long time = ULONG_MAX) 線程將會被阻塞,等待time毫秒。和sleep不一樣的是,若是線程退出,wait會返回。
狀態:isFinisged() isEunning() isInterruptionRequested()
class Worker : public QObject
{
Q_OBJECT
public slots:
void doWork(const QString ¶meter) {
QString result;
// 這裏是昂貴的或阻塞的操做
emit resultReady(result);
}
signals:
void resultReady(const QString &result);
};
class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
public:
Controller() {
Worker *worker = new Worker;
worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &Controller::operate, worker, &Worker::doWork);
connect(worker, &Worker::resultReady, this, &Controller::handleResults);
workerThread.start();
}
~Controller() {
workerThread.quit();
workerThread.wait();
}
public slots:
void handleResults(const QString &);
signals:
void operate(const QString &);
};
virtual void run()
{
int nValue = 0;
while (nValue < 100)
{
// 休眠50毫秒
msleep(50);
++nValue;
// 準備更新
emit resultReady(nValue);
}
}
signals:
void resultReady(int);
onnect(this,SIGNAL(resultReady(int)),this,SLOT(updateprogress(int))); connect(this,SIGNAL(finished()),this,SLOT(deleteLater()));
兩種訪問xml的方式,dom和sax,因爲dom是先儲存到內存裏面,對於頻繁的修改很強,sax逐行掃描文檔,一邊掃描一邊解析,隨時中止。
類 描述
QDomAttr 表示一個 QDomElement 的屬性
QDomCDATASection 表示一個 XML CDATA 部分
QDomCharacterData 表示 DOM 中的一個通用字符串
QDomComment 表示一個 XML 註釋
QDomDocument 表示一個 XML 文檔
QDomDocumentFragment QDomNodes 樹,一般不是一個完整的 QDomDocument
QDomDocumentType 表示文檔樹中的 DTD
QDomElement 表示 DOM 樹中的一個元素
QDomEntity 表明一個 XML 實體
QDomEntityReference 表明一個 XML 實體引用
QDomImplementation DOM 實現的功能的信息
QDomNamedNodeMap 包含一個節點集合,節點能夠經過名字來訪問
QDomNode 一個 DOM 樹中全部節點的基類
QDomNodeList QDomNode 對象列表
QDomNotation 表明一個 XML 表示法
QDomProcessingInstruction 表明 XML 處理指令
QDomText 表示解析的 XML 文檔中的文本數據
nt main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
QDomDocument doc("mydocument");
QFile file("/home/zz/Downloads/test.xml");
if (!file.open(QIODevice::ReadOnly))
return 0;
if (!doc.setContent(&file)) {
file.close();
return 0;
}
file.close();
// 打印出做爲最外層元素的全部直接子元素的元素名稱
QDomElement docElem = doc.documentElement();
// 這裏,咱們在文檔的末尾添加一個新元素
QDomElement elem = doc.createElement("img");
elem.setAttribute("src", "myimage.png");
docElem.appendChild(elem);
QDomNode n = docElem.firstChild();
while(!n.isNull()) {
QDomElement e = n.toElement(); // 嘗試將節點轉換爲元素
if(!e.isNull()) {
cout << qPrintable(e.tagName())<< endl; // 節點真的是一個元素
qDebug()<<e.text();
}
n = n.nextSibling();
}
QString str=doc.toString();
w.ui->textBrowser->setText(str);
return a.exec();
}
Introduce:
最經常使用的 DOM 類是 QDomNode、QDomDocument、QDomElement 和 QDomText。
建立文檔數據的多個函數,例如:createElement()、createTextNode()、createComment()、createCDATASection()、createProcessingInstruction()、createAttribute() 和 createEntityReference()。這些函數中的一些具備支持命名空間的版本,即:createElementNS() 和 createAttributeNS()。createDocumentFragment() 函數用於保存文檔的各部分,這對於處理複雜文檔頗有用。
能夠根據 elementsByTagName() 或 elementsByTagNameNS() 獲取具備特定標記的全部元素的列表。
void writeXML() {
QDomDocument doc;//new create
QDomProcessingInstruction xmlInstruction = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"");
QDomComment comment = doc.createComment(QString::fromLocal8Bit("This is a annotation"));
QDomProcessingInstruction styleInstruction = doc.createProcessingInstruction("xml-stylesheet", "type=\"text/css\" href=\"style.css\"");
doc.appendChild(xmlInstruction); // 開始文檔(XML 聲明)
doc.appendChild(comment); // 註釋
doc.appendChild(styleInstruction); // 處理指令
// 根元素 <studentinfo>
QDomElement root = doc.createElement("studentinfo");
root.setAttribute("Version", "1.0"); // 屬性
doc.appendChild(root);
// 元素
QDomElement message = doc.createElement("message");
root.appendChild(message);
// 元素
QDomElement name = doc.createElement(QString::fromLocal8Bit("name"));
QDomElement num = doc.createElement(QString::fromLocal8Bit("num"));
QDomElement instruction = doc.createElement(QString::fromLocal8Bit("instruction"));
message.appendChild(name);
message.appendChild(num);
message.appendChild(instruction);
// 元素的文本數據
QDomText nameText = doc.createTextNode(QString::fromLocal8Bit("zylg"));
QDomText numText = doc.createTextNode("1500710101");
QDomText instructionText = doc.createTextNode(QString::fromLocal8Bit("Like to sleep"));
name.appendChild(nameText);
num.appendChild(numText);
instruction.appendChild(instructionText);
// 保存 XML 文件
QString strFile("/home/zz/Downloads/test.xml");
QFile file(strFile);
if (file.open(QFile::WriteOnly | QFile::Text)) { // 只寫模式打開文件
QTextStream out(&file);
doc.save(out, QDomNode::EncodingFromDocument);
file.close();
}
}
void readXML() {
QDomDocument doc;
QFile file("/home/zz/Downloads/test.xml");
if (!file.open(QIODevice::ReadOnly))
return;
if (!doc.setContent(&file)) {
file.close();
return;
}
file.close();
/**********根元素 <Blogs>**********/
QDomElement root = doc.documentElement();
qDebug() << root.tagName();
if (root.hasAttribute("Version")) // 屬性
qDebug() << root.attribute("Version");
/**********根元素之上(XML 聲明、註釋等)**********/
QDomNode node = root.previousSibling();
while (!node.isNull()) {
switch (node.nodeType()) {
case QDomNode::ProcessingInstructionNode : {
QDomProcessingInstruction instruction = node.toProcessingInstruction();
qDebug() << instruction.target() << instruction.data();
if (QString::compare(instruction.target(), "xml") == 0) { // 開始文檔(XML 聲明)
// ...
} else if (QString::compare(instruction.target(), "xml-stylesheet") == 0) { // 處理指令
// ...
}
break;
}
case QDomNode::CommentNode : {
QDomComment comment = node.toComment();
qDebug() << comment.data();
break;
}
default:
break;
}
node = node.previousSibling();
}
/**********元素 <istudentinfo>**********/
node = root.firstChild(); // 返回根節點的第一個子節點
while (!node.isNull()) {
if (node.isElement()) {
QDomElement element = node.toElement(); // 嘗試將節點轉換爲元素
if (!element.isNull()) { // 節點的確是一個元素
qDebug() << element.tagName();
/**********遍歷元素 <name>、<num>、<introduce>**********/
QDomNodeList list = element.childNodes();
for (int i = 0; i < list.count(); i++) {
node = list.at(i);
if (node.isElement()) {
element = node.toElement();
qDebug() << element.tagName() << element.text();
if (QString::compare(element.tagName(), QStringLiteral("name")) == 0) {
// ...
} else if (QString::compare(element.tagName(), QStringLiteral("num")) == 0) {
// ...
} else if (QString::compare(element.tagName(), QStringLiteral("introduce")) == 0) {
// ...
}
}
}
}
}
node = node.nextSibling();
}
}
Sax2
類描述
QXmlAttributes用於向來是元素事件中傳遞屬性
QXmlLocator用於獲取事件的實際解析位置
QXmlNamespaceSupport用於爲讀取器實現命名空間支持
QXmlAttributes用於向來是元素事件中傳遞屬性
QXmlLocator用於獲取事件的實際解析位置
QXmlNamespaceSupport用於爲讀取器實現命名空間支持。
Qt 提供了兩個新的類來讀寫 XML:QXmlStreamReader 和 QXmlStreamWriter。
QXmlStreamReader xml;
...
while (!xml.atEnd()) {
xml.readNext();
... // 作處理
}
if (xml.hasError()) {
... // 作錯誤處理
}
QXmlStreamWriter stream(&output);
stream.setAutoFormatting(true);
stream.writeStartDocument();
...
stream.writeStartElement("bookmark");
stream.writeAttribute("href", "http://qt-project.org/");
stream.writeTextElement("title", "Qt Project");
stream.writeEndElement(); // bookmark
...
stream.writeEndDocument();
Note:dtd
void writeXML() {
QString strFile("/home/zz/Downloads/test.xml");
QFile file(strFile);
if (!file.open(QFile::WriteOnly | QFile::Text)) { // 只寫模式打開文件
qDebug() << QString("Cannot write file %1(%2).").arg(strFile).arg(file.errorString());
return;
}
//Start to write .xml file
QXmlStreamWriter out(&file);
out.setAutoFormatting(true);//format to auto set
out.writeStartDocument("1.0",true); //start to write in .xml
out.writeComment("This xml to introduce student info!");//it is annotation
out.writeProcessingInstruction("xml-stylesheet type=\"text/css\" href=\"style.css\""); // 處理指令
out.writeDTD("<!DOCTYPE studentinfo ["
"<!ENTITY Copyright \"zylg\">"
"<!ELEMENT studentinfo (identity,interesting)>"
"<!ELEMENT identity (name,age)>"
"<!ELEMENT name (#PCDATA)>"
"<!ELEMENT age (#PCDATA)>"
"<!ELEMENT interesting (one,two)>"
"<!ELEMENT one (#PCDATA)>"
"<!ELEMENT two (#PCDATA)>"
"]>");
out.writeStartElement("studentinfo");
out.writeAttribute("Version","1.0");
out.writeStartElement("identity");
out.writeTextElement("name","zylg");
out.writeTextElement("age","21");
out.writeEntityReference("Copyright");
// out.writeCharacters(">");
out.writeCDATA("add introduce");
out.writeEmptyElement("Empty");
out.writeEndElement();
out.writeStartElement("interesting");
out.writeTextElement("one","Play baskball");
out.writeTextElement("two","paly footballl");
out.writeEndElement();
out.writeEndElement();
out.writeEndDocument();
file.close(); // 關閉文件
}
void parseBlog(QXmlStreamReader &reader)
{
while (!reader.atEnd())
{
if(reader.isStartElement())
{
if(reader.name().toString()=="identity")
{
qDebug()<<"identity element";
}
else if(reader.name().toString()=="interesting")
{
qDebug()<<"interesting element";
}
}
else if(reader.name().toString()=="name")
{
QString str=reader.readElementText();
if(str==NULL)qDebug()<<"have nill text";
qDebug()<<"name:"<<str;
}
else if(reader.name().toString()=="age")
{
qDebug()<<"age:"<<reader.readElementText();
}
else if(reader.name().toString()=="one")
{
qDebug()<<"one:"<<reader.readElementText();
}
else if(reader.name().toString()=="two")
{
qDebug()<<"two:"<<reader.readElementText();
}
else if(reader.isEndElement())
{
if(reader.name().toString()=="identity")
{
qDebug()<<"</identity>";
}
else if(reader.name().toString()=="interesting")
{
qDebug()<<"</interesting>";
}
if(reader.name().toString()=="studentinfo")
{
qDebug()<<"</studentinfo>";
break;
}
}
reader.readNext();
}
}
void readXML()
{
QFile file("/home/zz/Downloads/test.xml");
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { // 以只寫模式打開文件
QXmlStreamReader reader(&file);
// 解析 XML,直到結束
while (!reader.atEnd()) {
// 讀取下一個元素
QXmlStreamReader::TokenType nType = reader.readNext();
switch (nType) {
case QXmlStreamReader::StartDocument:// 開始文檔
{
QString strVersion = reader.documentVersion().toString();
QString strEncoding = reader.documentEncoding().toString();
bool bAlone = reader.isStandaloneDocument();
qDebug() << QString::fromLocal8Bit("版本:%1 編碼:%2 Standalone:%3")
.arg(strVersion).arg(strEncoding).arg(bAlone) << "\r\n";
break;
}
case QXmlStreamReader::Comment:
{ // 註釋
qDebug() << QString::fromLocal8Bit("********** 註釋 ********** ");
QString strComment = reader.text().toString();
qDebug() << strComment << "\r\n";
break;
}
case QXmlStreamReader::ProcessingInstruction:
{ // 處理指令
qDebug() << QString::fromLocal8Bit("********** 處理指令 ********** ");
QString strProcInstr = reader.processingInstructionData().toString();
qDebug() << strProcInstr << "\r\n";
break;
}
case QXmlStreamReader::DTD:
{ // DTD
qDebug() << QString::fromLocal8Bit("********** DTD ********** ");
QString strDTD = reader.text().toString();
QXmlStreamNotationDeclarations notationDeclarations = reader.notationDeclarations(); // 符號聲明
QXmlStreamEntityDeclarations entityDeclarations = reader.entityDeclarations(); // 實體聲明
// DTD 聲明
QString strDTDName = reader.dtdName().toString();
QString strDTDPublicId = reader.dtdPublicId().toString(); // DTD 公開標識符
QString strDTDSystemId = reader.dtdSystemId().toString(); // DTD 系統標識符
qDebug() << QString::fromLocal8Bit("DTD : %1").arg(strDTD);
qDebug() << QString::fromLocal8Bit("DTD 名稱 : %1").arg(strDTDName);
qDebug() << QString::fromLocal8Bit("DTD 公開標識符 : %1").arg(strDTDPublicId);
qDebug() << QString::fromLocal8Bit("DTD 系統標識符 : %1").arg(strDTDSystemId);
qDebug() << "\r\n";
break;
}
case QXmlStreamReader::StartElement: { // 開始元素
QString strElementName = reader.name().toString();
if (QString::compare(strElementName, "studentinfo") == 0) { // 根元素
qDebug() << QString::fromLocal8Bit("********** 開始元素<studentinfo> ********** ");
QXmlStreamAttributes attributes = reader.attributes();
if (attributes.hasAttribute("Version")) {
QString strVersion = attributes.value("Version").toString();
qDebug() << QString::fromLocal8Bit("屬性:Version(%1)").arg(strVersion);
}
parseBlog(reader);
}
break;
}
case QXmlStreamReader::EndDocument: { // 結束文檔
qDebug() << QString::fromLocal8Bit("********** 結束文檔 ********** ");
break;
}
}
}
if (reader.hasError()) { // 解析出錯
qDebug() << QString::fromLocal8Bit("錯誤信息:%1 行號:%2 列號:%3 字符位移:%4").arg(reader.errorString()).arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.characterOffset());
}
file.close(); // 關閉文件
}
}
JSON 中的值有 6 種基本數據類型:
· bool(QJsonValue::Bool)
· double(QJsonValue::Double)
· string(QJsonValue::String)
· array(QJsonValue::Array)
· object(QJsonValue::Object)
· null(QJsonValue::Null)
#include "ui_mainwindow.h"
#include<QJsonArray>
#include <QApplication>
#include "mainwindow.h"
#include<QFile>
#include<QString>
#include<QTextStream>
#include<QDebug>
#include<QJsonObject>
#include<QJsonDocument>
#include<QJsonParseError>
QString getjsonbyarray(QByteArray bytearray)
{
QString strjson;
QJsonParseError jsonError;
QJsonDocument document=QJsonDocument::fromJson(bytearray,&jsonError);
if(!(!document.isNull() && jsonError.error==QJsonParseError::NoError))exit(0);
if (document.isObject()) // JSON 文檔爲對象
{
QJsonObject object = document.object(); // 轉化爲對象
if (object.contains("Name"))strjson.append(object.value("Name").toString()+"\n");
if (object.contains("Company"))strjson.append(object.value("Company").toString()+"\n");
if (object.contains("From"))strjson.append(QString::number(object.value("From").toInt(),10)+"\n");
if (object.contains("Version"))
{
QJsonValue value = object.value("Version");
if (value.isArray())
{ // Version 的 value 是數組
QJsonArray array = value.toArray();
int nSize = array.size();
for (int i = 0; i < nSize; ++i)
{
QJsonValue value = array.at(i);
strjson.append(QString::number(value.toDouble(),'f',3)+"\n");
}
}
}
if (object.contains("Page"))
{
QJsonValue value = object.value("Page");
if (value.isObject())
{
QJsonObject obj = value.toObject();
if (obj.contains("Home")) strjson.append(obj.value("Home").toString()+"\n");
if (obj.contains("Download")) strjson.append(obj.value("Down
load").toString()+"\n");
if (obj.contains("Developers"))strjson.append(obj.value("Developers").toString()+"\n");
}
}
}
return strjson;
}
QString createjson()
{// 構建 Json 數組 - Version
QJsonArray versionArray;
versionArray.append(4.8);
versionArray.append(5.2);
versionArray.append(5.7);
// 構建 Json 對象 - Page
QJsonObject pageObject;
pageObject.insert("Home", "https://www.qt.io/");
pageObject.insert("Download", "https://www.qt.io/download/");
pageObject.insert("Developers", "https://www.qt.io/developers/");
// 構建 Json 對象
QJsonObject json;
json.insert("Name", "Qt");
json.insert("Company", "Digia");
json.insert("From", 1991);
json.insert("Version", QJsonValue(versionArray));
json.insert("Page", QJsonValue(pageObject));
// 構建 Json 文檔
QJsonDocument document;
document.setObject(json);
QFile savefile("/home/zz/save.json");
if(!savefile.open(QFile::WriteOnly)){exit(0);}
QTextStream out(&savefile);
out<<document.toJson();
savefile.close();
QFile loadfile("/home/zz/save.json");
if(!loadfile.open(QFile::ReadOnly))exit(0);
QByteArray byteArray=loadfile.readAll();
loadfile.close();
// QByteArray byteArray = document.toJson(QJsonDocument::Compact);
QString strJson(byteArray);
return getjsonbyarray(byteArray);
// return strJson;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.resize(500,500);
w.show();
w.ui->textBrowser->setText(createjson());
return a.exec();
}
contains() 判斷一個指定的鍵是否存在
remove() 刪除相關的鍵
allKeys() 獲取全部鍵
clear() 刪除全部鍵
value()進行值的讀取
Setvalue()設置值
例子:
#include "mainwindow.h"
#include<QSettings>
#include <QApplication>
#include "ui_mainwindow.h"
#include<QString>
//#define HKEY_CURRENT_USER_QT " HKEY_CURRENT_USER\\Software\\QtProject\\OrganizationDefaults\\Qt";
//#define INI_QT "G:\test\Digia";
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QCoreApplication::setOrganizationName(QString("Digia"));//組織名
QCoreApplication::setApplicationName(QString("Qt"));//產品名
QSettings settings(QSettings::IniFormat, QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName());
//NativeFormat=HKEY_CURRENT_USER\Software
//IniFormat=C:\Users\zylg\AppData\Roaming
settings.setValue("Name", "Qt Creator");//寫入註冊表
settings.setValue("Version", 5);
settings.setValue("zylg", 5);
settings.setValue("l love the word", 5);
settings.beginGroup("name1");
settings.setValue("Name","zylg1");
settings.setValue("number",15007);
settings.beginGroup("son1");
settings.setValue("路過","12345");
settings.endGroup();
settings.endGroup();
settings.beginGroup("name2");
settings.setValue("Name","zylg2");
settings.setValue("number",15008);
settings.remove("Name");//刪除指定鍵,settings.clear()
settings.endGroup();
QString str=settings.value("Name").toString()+"\n";//讀取註冊表
str.append(QString::number(settings.value("zylg").toFloat(),'2',0)+"\n");
MainWindow w;
settings.beginGroup("name1");
settings.beginGroup("son1");
str.append(QString::number(settings.value("路過").toDouble(),'1',0));
settings.endGroup();
settings.endGroup();
QStringList strlist=settings.allKeys();
w.show();
w.ui->textBrowser->setText(str);
w.ui->textBrowser->append("遍歷輸出key and value:");
foreach (QString str, strlist )
{
w.ui->textBrowser->append(str+"="+settings.value(str).toString());
}
return a.exec();
}
第三方庫包含:.h .lib(不一樣編譯平臺不一樣) .dll
在 Windows 中,MinGW 將輸出 .a 和 .dll;MSVC 將輸出 .lib 和 .dll。
在 Linux 中,MinGW 將輸出 .so、.so.1、.so.1.0 和 .so.1.0.0 - .lib
只要在添加外部庫文件的時候添加lib文件進去,而後在用的地方放進去.h文件,就能夠編譯成功。若是想要獨立運行的時候,必須在exe文件的地方放入dll文件。
Windeployqt很強的打包文件windows下面使用
Linux下的ldd 能夠找到依賴文件 cp過去就好
#ifndef SHAREDLIB_GLOBAL_H
#define SHAREDLIB_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(SHAREDLIB_LIBRARY)
# define SHAREDLIBSHARED_EXPORT Q_DECL_EXPORT
#else
# define SHAREDLIBSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // SHAREDLIB_GLOBAL_H
#ifndef SHAREDLIB_H
#define SHAREDLIB_H
#include "sharedlib_global.h"
SHAREDLIBSHARED_EXPORT int sub(int x,int y);
class SHAREDLIBSHARED_EXPORT SharedLib
{
public:
SharedLib();
int add(int x,int y);
};
#endif // SHAREDLIB_H
運行時加載共享庫
QLibrary加載的流程(不用lib和.h文件了,一個dll搞定)
.構造QLibrary實例
.setFileName()指定共享庫的文件名
.load()動態加載共享庫,isload()判斷是否加載
.resolve()解析共享庫的符號
.unload()卸載共享庫
#include <QCoreApplication>
#include <QLibrary>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QLibrary lib("SharedLib"); // SharedLibd.dll 與可執行程序位於同一目錄
if (lib.load()) // 加載共享庫
{
typedef int (*Fun)(int, int); // 解析符號,fun指向函數的指針
Fun sub = (Fun) lib.resolve("subt");//解析函數名,把就必須爲c函數
if (sub)
{
int result = sub(5, 2);
qDebug() << result;
} else
{
qDebug() << "Can not resolve subtract";
}
lib.unload(); // 卸載共享庫
} else
{
qDebug() << lib.errorString();
}
return a.exec();
}
在windows能夠運行,可是linux不知道爲啥,弄不出來,暫留
加載靜態庫和動態庫時同樣的
加載靜態庫,在打包程序時就不用包括dll文件了
修改自己插件
基類 |
目錄 |
Qt 模塊 |
大小寫敏感性 |
QAccessibleBridgePlugin |
accessiblebridge |
Qt GUI |
區分大小寫 |
QImageIOPlugin |
imageformats |
Qt GUI |
區分大小寫 |
QPictureFormatPlugin (obsolete) |
pictureformats |
Qt GUI |
區分大小寫 |
QAudioSystemPlugin |
audio |
Qt Multimedia |
區分大小寫 |
QDeclarativeVideoBackendFactoryInterface |
video/declarativevideobackend |
Qt Multimedia |
區分大小寫 |
QGstBufferPoolPlugin |
video/bufferpool |
Qt Multimedia |
區分大小寫 |
QMediaPlaylistIOPlugin |
playlistformats |
Qt Multimedia |
區分大小寫 |
QMediaResourcePolicyPlugin |
resourcepolicy |
Qt Multimedia |
區分大小寫 |
QMediaServiceProviderPlugin |
mediaservice |
Qt Multimedia |
區分大小寫 |
QSGVideoNodeFactoryPlugin |
video/videonode |
Qt Multimedia |
區分大小寫 |
QBearerEnginePlugin |
bearer |
Qt Network |
區分大小寫 |
QPlatformInputContextPlugin |
platforminputcontexts |
Qt Platform Abstraction |
區分大小寫 |
QPlatformIntegrationPlugin |
platforms |
Qt Platform Abstraction |
區分大小寫 |
QPlatformThemePlugin |
platformthemes |
Qt Platform Abstraction |
區分大小寫 |
QGeoPositionInfoSourceFactory |
position |
Qt Positioning |
區分大小寫 |
QPlatformPrinterSupportPlugin |
printsupport |
Qt Print Support |
區分大小寫 |
QSGContextPlugin |
scenegraph |
Qt Quick |
區分大小寫 |
QScriptExtensionPlugin |
script |
Qt Script |
區分大小寫 |
QSensorGesturePluginInterface |
sensorgestures |
Qt Sensors |
區分大小寫 |
QSensorPluginInterface |
sensors |
Qt Sensors |
區分大小寫 |
QSqlDriverPlugin |
sqldrivers |
Qt SQL |
區分大小寫 |
QIconEnginePlugin |
iconengines |
Qt SVG |
區分大小寫 |
QAccessiblePlugin |
accessible |
Qt Widgets |
區分大小寫 |
QStylePlugin |
styles |
Qt Widgets |
區分大小寫 |
.pro file
QT += widgets
TEMPLATE = lib
CONFIG += plugin
TARGET = stylePlugin
HEADERS += \
simple_style.h \
style_plugin.h
OTHER_FILES += simple.json
win32 {
CONFIG(debug, release|debug):DESTDIR = ../debug/styles/
CONFIG(release, release|debug):DESTDIR = ../release/styles/
} else {
DESTDIR = ../styles/
}
這個東西很重要
.h file
#ifndef SIMPLE_STYLE_H
#define SIMPLE_STYLE_H
#include <QProxyStyle>
#include<QDebug>
class SimpleStyle : public QProxyStyle
{
Q_OBJECT
public:
SimpleStyle() {}
void polish(QPalette &palette) override
{
palette.setBrush(QPalette::ButtonText, Qt::red);
}
};
#endif // SIMPLE_STYLE_H
#ifndef STYLE_PLUGIN_H
#define STYLE_PLUGIN_H
#include <QStylePlugin>
#include "simple_style.h"
class StylePlugin : public QStylePlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "simple.json")
public:
StylePlugin() {}
QStyle *create(const QString &key) override
{
if (key.toLower() == "mystyle")
return new SimpleStyle();
return Q_NULLPTR;
}
};
#endif // STYLE_PLUGIN_H
.json
{
"Keys": ["mystyle"]
}
應用程序插件擴展
在這裏添加了類和json兩個東西,接口處標紅標記,此外在pro文件的DESTDIR兩個文件設置同樣,person.h文件複製到測試的文件夾
#-------------------------------------------------
#
# mylife.pro
#
#-------------------------------------------------
QT -= gui
QT +=core
TARGET = mlife
TEMPLATE = lib
CONFIG +=plugin
DEFINES += MYLIFE_LIBRARY
SOURCES += mylife.cpp \
HEADERS += mylife.h\
person.h
DESTDIR =../plugins/
DISTFILES += \
zylg.json
//mylife.h
#ifndef MYLIFE_H
#define MYLIFE_H
#include"person.h"
#include<QDebug>
#include<QObject>
class Mylife:public QObject,person
{
Q_OBJECT
Q_INTERFACES(person)
Q_PLUGIN_METADATA(IID myiid FILE "zylg.json")
public:
virtual void eat() Q_DECL_OVERRIDE;
virtual void sleep() Q_DECL_OVERRIDE;
virtual void work() Q_DECL_OVERRIDE;
};
#endif // MYLIFE_H
#ifndef PERSON_H
#define PERSON_H
#include <QtPlugin>
#include <QString>
class person
{
public:
virtual void eat()=0;
virtual void sleep()=0;
virtual void work()=0;
};
#define myiid "org.qt-project.Qt.Examples.person"
Q_DECLARE_INTERFACE(person, myiid)
#endif // PERSON_H
{
"author" : "zylg",
"date" : "2018/05/18",
"name" : "personPlugin",
"version" : "1.0.0",
"dependencies" : []
}
#include <QCoreApplication>
#include <QPluginLoader>
#include <QDir>
#include <QtDebug>
#include <QJsonObject>
#include <QJsonArray>
#include "person.h"
void loadPlugin()
{
// 進入插件目錄
QDir pluginsDir(qApp->applicationDirPath());
pluginsDir.cd("plugins");
qDebug()<<pluginsDir.path();
// 查找目錄中的全部插件
foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
qDebug()<<fileName;
QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
// 返回插件的根組件對象
QObject *pPlugin = loader.instance();
if (pPlugin != Q_NULLPTR) {
// 獲取元數據(名稱、版本、依賴)
QJsonObject json = loader.metaData().value("MetaData").toObject();
qDebug() << "********** MetaData **********";
qDebug() << json.value("author").toVariant();
qDebug() << json.value("date").toVariant();
qDebug() << json.value("name").toVariant();
qDebug() << json.value("version").toVariant();
qDebug() << json.value("dependencies").toArray().toVariantList();
// 訪問感興趣的接口
person *pPerson = qobject_cast<person *>(pPlugin);
if (pPerson != Q_NULLPTR) {
qDebug() << "********** IPerson **********";
pPerson->eat();
} else {
qWarning() << "qobject_cast falied";
}
}
}
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
loadPlugin();
return a.exec();
}
像素的繪製在該點的右下角,均可執行scale() rotate() translate()
基本繪製
文本顯示不全能夠由QtextOption來控制
QTextOption option(Qt::AlignLeft | Qt::AlignVCenter);
option.setWrapMode(QTextOption::WordWrap);
painter.drawText(rect(), QStringLiteral("這世界很美好"), option);
void MainWindow::paintEvent(QPaintEvent *event)
{
QFont font;
font.setItalic(true);
font.setBold(true);
font.setPointSize(20);
QPainter painter(this);
painter.setFont(font);
painter.setPen(Qt::red);
painter.drawText(QRect(0,0,100,100),Qt::AlignCenter,"zylg");
painter.setPen(QPen(Qt::blue,6));
painter.drawLine(QPointF(0,height()),QPoint(width()/2,height()/2));
painter.drawEllipse(QPointF(210, 140), 40, 40);
painter.setBrush(QColor(0,255,0));
painter.drawRect(50,100,100,100);
}
漸變
QLinearGradient 顯示從起點到終點的漸變。
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
// 設置漸變色
QLinearGradient linear(QPointF((width()-200/2), (height()-200)/2),QPointF((width()-200/2)/2,180));
linear.setColorAt(0, Qt::green);
linear.setColorAt(1,Qt::red);
// 設置畫刷填充
// linear.setSpread(QGradient::PadSpread);
linear.setSpread(QGradient::ReflectSpread);
// linear.setSpread(QGradient::RepeatSpread);
painter.setBrush(linear);
// 繪製橢圓
painter.drawRect(QRect((width()-200)/2, height()/2-100, 180, 180));
}
QRadialGradient 類以圓心爲中心顯示漸變。(cx, cy) 是中點,半徑(radius)是以中點爲圓心的圓的半徑,(fx, fy) 是漸變的起點。
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
// 設置漸變色
QRadialGradient linear(QPointF((width()/2), (height())/2),30,QPointF(0,180));
linear.setColorAt(0, Qt::green);
linear.setColorAt(1,Qt::red);
// 設置畫刷填充
// linear.setSpread(QGradient::PadSpread);
// linear.setSpread(QGradient::ReflectSpread);
linear.setSpread(QGradient::RepeatSpread);
painter.setBrush(linear);
// 繪製橢圓
painter.drawRect(QRect((width()-200)/2, height()/2-100, 180, 180));
}
QConicalGradient 在 (cx, cy) 座標上以角度 (angle) 爲中心顯示漸變
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
// 設置漸變色
QConicalGradient linear(QPointF((width()/2),height()/2),45);
linear.setColorAt(0, Qt::green);
linear.setColorAt(1,Qt::red);
// 設置畫刷填充
linear.setSpread(QGradient::PadSpread);
// linear.setSpread(QGradient::ReflectSpread);
linear.setSpread(QGradient::RepeatSpread);
// painter.setBrush(linear);
// 繪製橢圓
painter.drawRect(QRect((width()-200)/2, height()/2-100, 180, 180));
}
轉換
translate(qreal dx, qreal dy):平移 - 對座標系沿着 x 軸移動 dx、沿 y 軸移動 dy
scale(qreal sx, qreal sy):縮放 - 經過水平的 sx 和垂直的 sy 縮放座標系
rotate(qreal angle, Qt::Axis axis = Qt::ZAxis):旋轉 - 對指定的軸用給定的角度反時針旋轉座標系統
shear(qreal sh, qreal sv):扭曲 - 經過水平的 sh 和垂直的 sv 扭曲座標系
reset():重置爲單位矩陣
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.drawPixmap(QRect(0, 0, 160, 160),QPixmap("../wangzai.jpg"));
QTransform transform;
transform.translate(120,20);
painter.setTransform(transform);
painter.drawPixmap(QRect(0, 0, 160, 160),QPixmap("../wangzai.jpg"));
transform.reset();
transform.rotate(45,Qt::XAxis);
painter.setTransform(transform);
painter.drawPixmap(QRect(280, 0, 160, 160),QPixmap("../wangzai.jpg"));
transform.reset();
transform.shear(0.5,0);
transform.rotate(45,Qt::YAxis);
painter.setTransform(transform);
painter.drawPixmap(QRect(0, 180, 160, 160),QPixmap("../wangzai.jpg"));
transform.reset();
transform.scale(0.5,0.5);
transform.rotate(45,Qt::ZAxis);
painter.setTransform(transform);
painter.drawPixmap(QRect(420, -60, 160, 160),QPixmap("../wangzai.jpg"));
}
QPainterPath
裏面的moveTo() cubicTo() lineTo()最基本的構成元素,能夠組合爲其餘的東西
QPainterPathStroker
· setWidth():寬度
· setCapStyle():端點風格
· setJoinStyle():鏈接樣式
· setDashPattern():虛線圖案
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainterPath path;
path.addRect((width()-240)/2, (height()-240)/2, 240, 240);
path.moveTo((width()-400)/2, (height()-400)/2);
path.cubicTo(449, 50, 250, 250, 449, 449);
path.cubicTo(50, 449, 250, 250, 50, 50);
QPainter painter(this);
painter.fillRect((width()-400)/2, (height()-400)/2,400,400, Qt::white);
painter.setPen(QPen(QColor(79, 106, 25), 1, Qt::SolidLine,
Qt::FlatCap, Qt::MiterJoin));
painter.setBrush(QColor(122, 163, 39));
painter.drawPath(path);
}
void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
// 矩形 300 * 200
QRectF rect(50, 50, 300, 200);
QPainterPath path;
path.addRect(rect);
// 繪製原始路徑
painter.drawPath(path);
// 生成可填充的輪廓
QPainterPathStroker stroker;
stroker.setCapStyle(Qt::RoundCap); // 端點風格
stroker.setJoinStyle(Qt::RoundJoin); // 鏈接樣式
stroker.setDashPattern(Qt::DashLine); // 虛線圖案
stroker.setWidth(10); // 寬度
// 繪製輪廓
painter.setPen(Qt::green);
painter.fillPath(stroker.createStroke(path),QBrush(Qt::yellow));
}
圓形:
void drawimage(QPainter *painter,int radius,int startAngle,QRgb color)
{
// 漸變色
QRadialGradient gradient(0, 0, radius);
gradient.setColorAt(0, Qt::white);
gradient.setColorAt(1.0, color);
painter->setBrush(gradient);
QRectF rect(-radius, -radius, radius << 1, radius << 1);
QPainterPath path;
path.arcTo(rect, startAngle, 45);
painter->setPen(Qt::NoPen);
painter->drawPath(path);
}
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
int radius = 150;
painter.translate(width() >> 1, height() >> 1);;
drawimage(&painter,radius,0,qRgb(200,200,0));
drawimage(&painter,radius,45,qRgb(200,0,200));
drawimage(&painter,radius,90,qRgb(200,0,0));
drawimage(&painter,radius,135,qRgb(0,200,0));
drawimage(&painter,radius,180,qRgb(150,200,0));
drawimage(&painter,radius,225,qRgb(150,0,0));
drawimage(&painter,radius,270,qRgb(200,100,0));
drawimage(&painter,radius,315,qRgb(200,20,0));
}
void drawimage(QPainter *painter,int radius,int startAngle,QRgb color)
{
// 漸變色
QRadialGradient gradient(0, 0, radius);
gradient.setColorAt(0, Qt::white);
gradient.setColorAt(1.0, color);
painter->setBrush(gradient);
QRectF rect(-radius, -radius, radius << 1, radius << 1);
QPainterPath path;
path.arcTo(rect, startAngle, 45);
QPainterPath subpath;
subpath.addEllipse(rect.adjusted(30,30,-30,-30));
path-=subpath;
painter->setPen(Qt::NoPen);
painter->drawPath(path);
}
void drawimage(QPainter *painter,int radius,int startAngle,QRgb color)
{
// 漸變色
QRadialGradient gradient(0, 0, radius);
gradient.setColorAt(0, Qt::white);
gradient.setColorAt(1.0, color);
painter->setBrush(gradient);
QRectF rect(-radius, -radius, radius << 1, radius << 1);
QPainterPath path;
path.arcTo(rect, startAngle, 45);
QPainterPath subpath;
subpath.addEllipse(rect.adjusted(30,30,-30,-30));
path-=subpath;
QFont font;
font.setPointSize(15);
path.addText(path.pointAtPercent(0.5),font,"i love the world");
painter->setPen(Qt::NoPen);
painter->drawPath(path);
}
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.translate(width()/2,height()/2);
painter.rotate(ang);
painter.translate(0-width()/2,0-height()/2);
int radius = 150;
painter.translate(width() >> 1, height() >> 1);;
drawimage(&painter,radius,0,qRgb(200,200,0));
drawimage(&painter,radius,45,qRgb(200,0,200));
drawimage(&painter,radius,90,qRgb(200,0,0));
drawimage(&painter,radius,135,qRgb(0,200,0));
drawimage(&painter,radius,180,qRgb(150,200,0));
drawimage(&painter,radius,225,qRgb(150,0,0));
drawimage(&painter,radius,270,qRgb(200,100,0));
drawimage(&painter,radius,315,qRgb(200,20,0));
}
放一個定時器改變ang的大小便可
#include "mainwindow.h"
#include<QPainter>
#include<QTime>
#include<QTimer>
#include<QColor>
#include<QFont>
#include<qmath.h>
#include<QTransform>
MainWindow::MainWindow(QWidget *parent)
: QWidget(parent)
{
setWindowTitle("zylg");
QTimer *pTimer = new QTimer(this);
pTimer->setInterval(1);
connect(pTimer, SIGNAL(timeout()),this,SLOT(update()));
pTimer->start();
}
MainWindow::~MainWindow()
{
}
QRectF MainWindow::textRectF(double radius, int pointSize, double angle)
{
QRectF rectF;
rectF.setX(radius*qCos(angle*M_PI/180.0) - pointSize*2);
rectF.setY(radius*qSin(angle*M_PI/180.0) - pointSize/2.0);
rectF.setWidth(pointSize*4);
rectF.setHeight(pointSize);
return rectF;
}
void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
// 時針、分針、秒針位置 - 多邊形
static const QPoint hourHand[3] =
{
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -30)
};
static const QPoint minuteHand[3] =
{
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -65)
};
static const QPoint secondHand[3] =
{
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -80)
};
// 時針、分針、秒針顏色
QColor hourColor(200, 100, 0, 200);
QColor minuteColor(0, 227, 127, 150);
QColor secondColor(0, 250, 230, 150);
int side = qMin(width(), height());
QTime time = QTime::currentTime();
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// 平移座標系原點至中心點
painter.translate(width() / 2, height() / 2);
// 縮放
painter.scale(side / 200.0, side / 200.0);
// 繪製時針
painter.setPen(Qt::NoPen);
painter.setBrush(hourColor);
painter.save();
// 每圈360° = 12h 即:旋轉角度 = 小時數 * 30°
painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
painter.drawConvexPolygon(hourHand, 3);
painter.restore();
painter.setPen(hourColor);
// 繪製小時線 (360度 / 12 = 30度)
for (int i = 0; i < 12; ++i)
{
painter.drawLine(88, 0, 96, 0);
painter.rotate(30.0);
}
int radius = 100;
QFont font = painter.font();
font.setBold(true);
painter.setFont(font);
int pointSize = font.pointSize();
// 繪製小時文本
int nHour = 0;
for (int i = 0; i < 12; ++i)
{
nHour = i+3 ;
if (nHour > 12)
nHour -= 12;
painter.drawText(textRectF(radius*0.8, pointSize, i * 30), Qt::AlignCenter, QString::number(nHour));
}
// 繪製分針
painter.setPen(Qt::NoPen);
painter.setBrush(minuteColor);
painter.save();
// 每圈360° = 60m 即:旋轉角度 = 分鐘數 * 6°
painter.rotate(6.0 * (time.minute() + time.second() / 60.0));
painter.drawConvexPolygon(minuteHand, 3);
painter.restore();
painter.setPen(minuteColor);
// 繪製分鐘線 (360度 / 60 = 6度)
for (int j = 0; j < 60; ++j)
{
if ((j % 5) != 0)
painter.drawLine(92, 0, 96, 0);
painter.rotate(6.0);
}
// 繪製秒針
painter.setPen(Qt::NoPen);
painter.setBrush(secondColor);
painter.save();
// 每圈360° = 60s 即:旋轉角度 = 秒數 * 6°
painter.rotate(6.0 * time.second());
painter.drawConvexPolygon(secondHand, 3);
painter.restore();
}
Imagewrite and imagereader
公共函數
void setFileName(const QString & fileName)
void setFormat(const QByteArray & format)
void setText(const QString & key, const QString & text)
bool supportsOption(QImageIOHandler::ImageOption option) const //png格式容許嵌入文字
void setQuality(int quality) 設置圖像格式的質量。
#include "mainwindow.h"
#include<QImage>
#include<QImageWriter>
#include<QDebug>
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QImage img("/home/zz/qt/wangzaicd ../");
QImageWriter write("wangzaiLogo.jpeg","jpeg");
if(write.supportsOption(QImageIOHandler::Description))
{
write.setText("AUthor","zylg");
write.setText("date","2018/5/23");
}
write.setQuality(100);
if(write.canWrite())write.write(img);
else qDebug()<<write.errorString();
// MainWindow w;
// w.resize(500,500);
// w.show();
return a.exec();
}
QImageReader
void setFileName(const QString &filename)
void setFormat(const QByteArray & format)
QStringList textKeys() const //返回此圖片全部的keys
QString text(const QString & key)// const返回對應的key
bool supportsOption(QImageIOHandler::ImageOption option) const
void setQuality(int quality)
bool supportsAnimation() const //是否支持動畫
int loopCount() const //動畫的循環次數
int nextImageDelay() const //動畫下一幀等待的秒數
int imageCount() const //動畫圖像的總數
int currentImageNumber() const //當前幀的序號
bool jumpToImage(int imageNumber) 跳到指定的序號圖像
bool jumpToNextImage()
bool canRead() const
bool read(QImage * image)
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QImageReader reader;
reader.setFileName("../painter001/wangzaiLogo.jpeg");
if(reader.canRead())
{
QStringList keys=reader.textKeys();
QString strvalue("");
foreach (QString str, keys)
{
strvalue=reader.text(str);
qDebug()<<QString("Key %1 value %2").arg(str).arg(strvalue);
}
}
else
{
qDebug()<<reader.errorString();
}
return a.exec();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QImageReader reader;
reader.setFileName("../1");
if (reader.supportsAnimation())
{
// 動畫循環的次數
int nLoopCount = reader.loopCount();
qDebug() << QString("Loop Count : %1").arg(nLoopCount);
int nCount = reader.imageCount();
for (int i = 0; i < nCount; ++i)
{
// 跳到順序號爲i的圖像
bool ret = reader.jumpToImage(i);
if (reader.canRead())
{
// 讀取圖像
QImage image = reader.read();
// 保存圖像
image.save(QString("Loading%1.jpeg").arg(i + 1));
// 下一幀動畫等待的毫秒數
int nDelay = reader.nextImageDelay();
qDebug() << QString("Number %1 Delay : %2").arg(i + 2).arg(nDelay);
}
else
{
// 獲取錯誤信息
QImageReader::ImageReaderError error = reader.error();
QString strError = reader.errorString();
qDebug() << "Last Error : " << strError;
}
}
}
return a.exec();
}
1.場景:
QGraphicsScene提供了圖形視圖場景,時item的容器
· 提供一個快速的接口,用於管理大量圖元
· 向每一個圖元傳遞事件
· 管理圖元的狀態,如:選中、焦點處理
· 提供未進行座標轉換的渲染功能,主要用於打印
QGraphicsScene::addItem()將圖元添加到場景
QGraphicsScene::items()函數及其重載函數能夠返回全部圖元
QGraphicsScene::itemAt()返回在特定點上最上面的圖元,最後返回的時最下層的
QGraphicsScene::setFocusItem()或QGraphicsItem::setFocus()爲一個圖元設置焦點,或經過QGraphicsScene::focusItem()獲取當前的焦點圖元。
QGraphicsScene::render()和QGraphicsView::render()
視圖:
圖元:
· 鼠標按下、移動、釋放和雙擊事件,以及鼠標懸浮事件、滾輪事件和上下文菜單事件。
· 鍵盤輸入焦點和鍵盤事件。
· 拖放。
· 分組:經過父子關係,或QGraphicsItemGroup。
· 碰撞檢測。
打印:
QGraphicsScene scene;
scene.addRect(QRectF(0, 0, 100, 200), QPen(Qt::black), QBrush(Qt::green));
QPixmap pixmap;
QPainter painter(&pixmap);
painter.setRenderHint(QPainter::Antialiasing);
scene.render(&painter);
painter.end();
pixmap.save("scene.png");
常見的圖元:
· QGraphicsSimpleTextItem:提供了一個簡單的文本標籤項
· QGraphicsTextItem:提供了一個格式化的文本項
· QGraphicsLineItem:提供了一個直線項
· QGraphicsPixmapItem:提供了一個圖像項
· QGraphicsRectItem:提供了一個矩形項
· QGraphicsEllipseItem:提供了一個橢圓項
· QGraphicsPathItem:提供了一個路徑項
· QGraphicsPolygonItem:提供了一個多邊形項
文本
QGraphicsTextItem格式化文本項
QGraphicsTextItem *textitem=new QGraphicsTextItem();
QString strHTML = QString("<html> \
<head> \
<style> \
font{color:white;} #f{font-size:18px; color: #00A0E6;} \
</style> \
</head> \
<body>\
<font>%1</font><font id=\"f\">%2</font> \
<br/><br/> \
<a href=\"www.baidu.com\"><img src=\"../wangzai1.jpg\" width=\"100\" height=\"100\"> <\a>\
</body> \
</html>").arg("I am a ").arg("Qter");
textitem->setHtml(strHTML);
textitem->setOpenExternalLinks(true);
textitem->setTextInteractionFlags(Qt::TextBrowserInteraction);
connect(textitem, &QGraphicsTextItem::linkActivated, [=](QString link) {
QDesktopServices::openUrl(QUrl(link));
});
QFont font=textitem->font();
font.setPixelSize(20);
font.setUnderline(true);
textitem->setFont(font);
//add text to scene
QGraphicsScene *scene=new QGraphicsScene();
scene->addItem(textitem);
//display scene on view
QGraphicsView *view=new QGraphicsView();
view->setScene(scene);
view->setStyleSheet("border:none;background:transparent;");
view->show();
QGraphicsSimpleTextItem
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsSimpleTextItem *textitem=new QGraphicsSimpleTextItem();
textitem->setText("my name is zylg");
QFont font=textitem->font();
font.setPixelSize(20);
font.setUnderline(true);
textitem->setFont(font);
textitem->setBrush(Qt::green);
//add text to scene
QGraphicsScene *scene=new QGraphicsScene();
scene->addItem(textitem);
//display scene on view
QGraphicsView *view=new QGraphicsView();
view->setScene(scene);
view->setStyleSheet("border:none;background:transparent;");
view->show();
return a.exec();
}
textitem->setPlainText("my name is zykg");
QFont font=textitem->font();
font.setPixelSize(20);
textitem->setDefaultTextColor(Qt::green);
font.setUnderline(true);
textitem->setFont(font);
textitem->setTextInteractionFlags(Qt::TextEditorInteraction);//can edit text
直線:
QGraphicsLineItem *line = new QGraphicsLineItem();
// 設置直線位於 (x1, y1) 和 (x2, y2)之間
line->setLine(QLineF(0, 0, 100, 100));
圖像:
// 定義一個 item
QGraphicsPixmapItem *pItem = new QGraphicsPixmapItem();
QPixmap image(":/Images/logo");
pItem->setPixmap(image.scaled(50, 50));
矩形:
// 定義一個 item
QGraphicsRectItem *pItem = new QGraphicsRectItem();
// 矩形區域 起點:(50, 50) 寬:100 高:100
pItem->setRect(QRectF(50, 50, 100, 100));
圓:
path:
pItem->setPath(starPath);
多邊形:
// 繪製多邊形
QPolygonF polygon;
polygon << QPointF(200.0, 120.0) << QPointF(230.0, 130.0)
<< QPointF(260.0, 180.0) << QPointF(200.0, 200.0);
pItem->setPolygon(polygon);
嵌入Qwidget(狀態同步)
QGraphicsScene scene;
QGraphicsProxyWidget *pProxy = scene.addWidget(pGroupBox);
QGraphicsView view(&scene);
view.show();
QGraphicsWidget *pWidget = new QGraphicsWidget();
pWidget->setLayout(pLayout);
// 將 item 添加至場景中
pScene->addItem(pWidget);
// 爲視圖設置場景
QGraphicsView *pView = new QGraphicsView();
pView->setScene(pScene);
pView->show();
QGraphicsScene管理QGraphicsItem(單擊/選擇/移動/縮放/刪除):
操做細節主要包括:
· 選擇:點擊左鍵、按 Shift 鍵能夠單選,按下 Ctrl 可進行多選。
· 添加:點擊左鍵
· 刪除:點擊右鍵,刪除鼠標下的 item;當按下 Ctrl 選擇多個 items 時,按下 Backspace 鍵,將選中的所有刪除。
· 移動:點擊左鍵,選擇 item,而後移動鼠標;當按下 Ctrl 選擇多個 items 時,能夠移動選中的 items。
· 縮放:按 Alt 鍵,而後鼠標拖拽 item 的邊界。
#ifndef CUSTOM_ITEM_H
#define CUSTOM_ITEM_H
#include <QGraphicsRectItem>
#include <QGraphicsScene>
//QGraphicsScene管理QGraphicsItem(單擊/選擇/移動/縮放/刪除)
// 自定義 Item
class CustomItem : public QGraphicsRectItem
{
public:
explicit CustomItem(QGraphicsItem *parent = 0);
protected:
// Shift+左鍵:進行選擇 Alt:準備縮放
void mousePressEvent(QGraphicsSceneMouseEvent *event);
// Alt+拖拽:進行縮放 移動
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
// 使item可以使用qgraphicsitem_cast
int type() const;
private:
QPointF m_centerPointF;
bool m_bResizing;
};
// 自定義 Scene
class CustomScene : public QGraphicsScene
{
protected:
// 左鍵:添加item 右鍵:移除item
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
// Backspace鍵移除item
void keyPressEvent(QKeyEvent *event);
};
#endif // CUSTOM_ITEM_H
#include "customitem.h"
#include <QKeyEvent>
#include <QGraphicsSceneMouseEvent>
#include <QDebug>
// 自定義 Item
CustomItem::CustomItem(QGraphicsItem *parent)
: QGraphicsRectItem(parent)
{
// 畫筆 - 邊框色
QPen p = pen();
p.setWidth(2);
p.setColor(QColor(0, 160, 230));
setPen(p);
// 畫刷 - 背景色
setBrush(QColor(247, 160, 57));
// 可選擇、可移動
setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable);
}
void CustomItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
if (event->modifiers() == Qt::ShiftModifier)
{
qDebug() << "Custom item left clicked with shift key.";
// 選中 item
setSelected(true);
}
else if (event->modifiers() == Qt::AltModifier)
{
qDebug() << "Custom item left clicked with alt key.";
// 重置 item 大小
double radius = boundingRect().width() / 2.0;
QPointF topLeft = boundingRect().topLeft();
m_centerPointF = QPointF(topLeft.x() + pos().x() + radius, topLeft.y() + pos().y() + radius);
QPointF pos = event->scenePos();
qDebug() << boundingRect() << radius << this->pos() << pos << event->pos();
double dist = sqrt(pow(m_centerPointF.x()-pos.x(), 2) + pow(m_centerPointF.y()-pos.y(), 2));
if (dist / radius > 0.8)
{
qDebug() << dist << radius << dist / radius;
m_bResizing = true;
}
else
{
m_bResizing = false;
}
}
else
{
qDebug() << "Custom item left clicked.";
QGraphicsItem::mousePressEvent(event);
event->accept();
}
}
else if (event->button() == Qt::RightButton)
{
qDebug() << "Custom item right clicked.";
event->ignore();
}
}
void CustomItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if ((event->modifiers() == Qt::AltModifier) && m_bResizing)
{
QPointF pos = event->scenePos();
double dist = sqrt(pow(m_centerPointF.x()-pos.x(), 2) + pow(m_centerPointF.y()-pos.y(), 2));
setRect(m_centerPointF.x()-this->pos().x()-dist, m_centerPointF.y()-this->pos().y()-dist, dist*2, dist*2);
}
else if(event->modifiers() != Qt::AltModifier)
{
qDebug() << "Custom item moved.";
QGraphicsItem::mouseMoveEvent(event);
qDebug() << "moved" << pos();
}
}
void CustomItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if ((event->modifiers() == Qt::AltModifier) && m_bResizing)
{
m_bResizing = false;
}
else
{
QGraphicsItem::mouseReleaseEvent(event);
}
}
int CustomItem::type() const
{
return UserType + 1;
}
// 自定義 Scene
void CustomScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
qDebug() << "Custom scene clicked.";
QGraphicsScene::mousePressEvent(event);
if (!event->isAccepted())
{
if (event->button() == Qt::LeftButton)
{
// 在 Scene 上添加一個自定義 item
QPointF point = event->scenePos();
CustomItem *item = new CustomItem();
item->setRect(point.x()-25, point.y()-25, 60, 60);
addItem(item);
}
else if (event->button() == Qt::RightButton)
{
// 檢測光標下是否有 item
QGraphicsItem *itemToRemove = NULL;
foreach (QGraphicsItem *item, items(event->scenePos()))
{
if (item->type() == QGraphicsItem::UserType+1)
{
itemToRemove = item;
break;
}
}
// 從 Scene 上移除 item
if (itemToRemove != NULL)
removeItem(itemToRemove);
}
}
}
void CustomScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
qDebug() << "Custom scene moved.";
QGraphicsScene::mouseMoveEvent(event);
}
void CustomScene::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Backspace)
{
// 移除全部選中的 items
qDebug() << "selected items " << selectedItems().size();
while (!selectedItems().isEmpty())
{
removeItem(selectedItems().front());
}
}
else
{
QGraphicsScene::keyPressEvent(event);
}
}
#include <QApplication>
#include <QGraphicsView>
#include "customitem.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// 建立 item
CustomItem *pItem = new CustomItem();
pItem->setRect(20, 20, 60, 60);
// 將 item 添加至場景中
CustomScene scene;
scene.setSceneRect(0, 0, 400, 300);
scene.addItem(pItem);
// 爲視圖設置場景
QGraphicsView view;
view.setScene(&scene);
view.show();
return a.exec();
}
只是一些事件的應用,懶得看也行
QGraphicsItemGroup圖元分組
// 構造 group、橢圓、直線、矩形
QGraphicsItemGroup *pGroup = new QGraphicsItemGroup();
QGraphicsEllipseItem *pFrom = new QGraphicsEllipseItem();
QGraphicsLineItem *pLink = new QGraphicsLineItem();
QGraphicsRectItem *pTo = new QGraphicsRectItem();
// 設置 group 可選中、可移動
pGroup->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable);
// 設置樣式(畫筆 - 邊框色 畫刷 - 背景色)
QPen pen = pFrom->pen();
pen.setWidth(2);
pen.setColor(QColor(0, 160, 230));
pFrom->setPen(pen);
pLink->setPen(pen);
pTo->setPen(pen);
pFrom->setBrush(QColor(247, 160, 57));
pTo->setBrush(QColor(247, 160, 57));
// 將 item 添加至 group
pGroup->addToGroup(pFrom);
pGroup->addToGroup(pTo);
pGroup->addToGroup(pLink);
// 設置橢圓、矩形區域
const double length = 50;
pFrom->setRect(QRectF(-length/2.0, -length/2.0, length, length));
pTo->setRect(QRectF(-length/2.0, -length/2.0, length, length));
// 設置橢圓、矩形、鏈接線座標
pFrom->setPos(80, 80);
pTo->setPos(200, 150);
pLink->setLine(QLineF(pFrom->pos(), pTo->pos()));
// 將 group 添加至場景中
QGraphicsScene *pScene = new QGraphicsScene();
pScene->setSceneRect(0, 0, 300, 200);
pScene->addItem(pGroup);
// 爲視圖設置場景
QGraphicsView *pView = new QGraphicsView();
pView->setRenderHint(QPainter::Antialiasing);
pView->setScene(pScene);
pView->show();
分組的事件處理
void QGraphicsItem::setHandlesChildEvents(bool enabled)
自定義選址選中樣式
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) Q_DECL_OVERRIDE
{
QStyleOptionGraphicsItem op;
op.initFrom(widget);
// 判斷選中時,設置狀態爲 State_None
if (option->state & QStyle::State_Selected)
op.state = QStyle::State_None; ;
// 調用默認方法,進行原始繪製
QGraphicsEllipseItem::paint(painter, &op, widget);
// 選中時繪製
if (option->state & QStyle::State_Selected) {
qreal itemPenWidth = pen().widthF();
const qreal pad = itemPenWidth / 2;
const qreal penWidth = 0;
// 邊框區域顏色
QColor color = QColor(Qt::yellow);
// 繪製實線
painter->setPen(QPen(color, penWidth, Qt::SolidLine));
painter->setBrush(Qt::NoBrush);
painter->drawRect(boundingRect().adjusted(pad, pad, -pad, -pad));
// 繪製虛線
painter->setPen(QPen(color, 0, Qt::DashLine));
painter->setBrush(Qt::NoBrush);
painter->drawRect(boundingRect().adjusted(pad, pad, -pad, -pad));
}
}
類 |
描述 |
QAbstractAnimation |
全部動畫類的基類 |
QAnimationGroup |
動畫容器類的抽象基類 |
QEasingCurve |
動畫控制的緩和曲線類 |
QParallelAnimationGroup |
並行動畫容器 |
QPauseAnimation |
QSequentialAnimationGroup暫停 |
QPropertyAnimation |
Qt的動畫屬性 |
QSequentialAnimationGroup |
串行動畫容器 |
QTimeLine |
控制動畫的時間軸類 |
QVariantAnimation |
動畫類的抽象基類 |
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QPushButton button("Animated Button");
button.show();
QPropertyAnimation animation(&button, "geometry");
animation.setDuration(10000);
// animation.setStartValue(QRect(0, 0, 100, 30));
// animation.setEndValue(QRect(250, 250, 100, 30));
animation.setKeyValueAt(0, QRect(0, 0, 100, 30));
animation.setKeyValueAt(0.8, QRect(250, 250, 100, 30));
animation.setKeyValueAt(1, QRect(0, 0, 100, 30));
animation.setEasingCurve(QEasingCurve::OutBounce);//along the line
animation.start();
return a.exec();
}
動畫分組
QPushButton button("Animated Button");
QPushButton *bonnie = new QPushButton("Bonnie");
bonnie->show();
QPushButton *clyde = new QPushButton("Clyde");
clyde->show();
// 動畫一
QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "geometry");
// 動畫二
QPropertyAnimation *anim2 = new QPropertyAnimation(clyde, "geometry");
QParallelAnimationGroup *group = new QParallelAnimationGroup;
group->addAnimation(anim1);
group->addAnimation(anim2);
group->start();
點擊移動
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QPushButton *button = new QPushButton("Animated Button");
button->show();
QStateMachine *machine = new QStateMachine;
QState *state1 = new QState(machine);
state1->assignProperty(button, "geometry", QRect(500, 500, 100, 30));
machine->setInitialState(state1);
QState *state2 = new QState(machine);
state2->assignProperty(button, "geometry", QRect(250, 250, 100, 30));
QSignalTransition *transition1 = state1->addTransition(button,
SIGNAL(clicked()), state2);
transition1->addAnimation(new QPropertyAnimation(button, "geometry"));
QSignalTransition *transition2 = state2->addTransition(button,
SIGNAL(clicked()), state1);
transition2->addAnimation(new QPropertyAnimation(button, "geometry"));
machine->start();
return a.exec();
}
自定義屬性之改變透明度
#ifndef MAIN_WINDOW_H
#define MAIN_WINDOW_H
...
class MainWindow : public CustomWindow
{
Q_OBJECT
Q_PROPERTY(int alpha READ alpha WRITE setAlpha)
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
int alpha() const;
void setAlpha(const int alpha);
private:
int m_nAlpha;
QLabel *m_pLabel;
};
#endif // MAIN_WINDOW_H
void MainWindow::setAlpha(const int alpha)
{
m_nAlpha = alpha;
QString strQSS = QString("color: rgb(0, 160, 230); background-color: rgba(10, 160, 105, %1);").arg(m_nAlpha);
m_pLabel->setStyleSheet(strQSS);
}
QPropertyAnimation *pAnimation = new QPropertyAnimation();
pAnimation->setTargetObject(this);
pAnimation->setPropertyName("alpha");
pAnimation->setDuration(1000);
pAnimation->setKeyValueAt(0, 255);
pAnimation->setKeyValueAt(0.5, 100);
pAnimation->setKeyValueAt(1, 255);
pAnimation->setLoopCount(-1); //永遠運行,直到stop
動畫的組操做
(1)單操做
m_pGroup = new QSequentialAnimationGroup(this);
// 添加動畫
m_pGroup->addAnimation(pAnimation1);
// 暫停1秒
m_pGroup->addPause(1000);
m_pGroup->addAnimation(pAnimation2);
// 循環2次
m_pGroup->setLoopCount(2);
// 從後向前執行
m_pGroup->setDirection(QAbstractAnimation::Backward);
(2)並行操做
m_pGroup = new QParallelAnimationGroup(this);
// 添加動畫
m_pGroup->addAnimation(pAnimation1);
m_pGroup->addAnimation(pAnimation2);
// 循環2次
m_pGroup->setLoopCount(2);
(3)暫停
// 暫停 - 特殊的動畫
QPauseAnimation *pPauseAnimation = new QPauseAnimation(this);
pPauseAnimation->setDuration(1000);
// 添加動畫
m_pGroup->addAnimation(pAnimation1);
m_pGroup->addAnimation(pPauseAnimation);
m_pGroup->addAnimation(pAnimation2);
時間控制
QProgressBar *progressBar = new QProgressBar(this);
progressBar->setRange(0, 100);
// 構造幀範圍爲 0 - 100,持續時間爲 1000 毫秒(1 秒)的 timeline
QTimeLine *timeLine = new QTimeLine(1000, this);
timeLine->setFrameRange(0, 100);
connect(timeLine, SIGNAL(frameChanged(int)), progressBar, SLOT(setValue(int)));
// 輸出當前幀數
connect(timeLine, &QTimeLine::frameChanged, [=](int value) {
qDebug() << value;
});
// 啓動進度條動畫
QPushButton *startButton = new QPushButton(this);
startButton->setText(QString::fromLocal8Bit("開始"));
connect(startButton, SIGNAL(clicked()), timeLine, SLOT(start()));
下墜效果
void MainWindow::onDropWindow()
{
QPropertyAnimation *pAnimation = new QPropertyAnimation(this, "geometry");
QDesktopWidget *pDesktopWidget = QApplication::desktop();
int x = (pDesktopWidget->availableGeometry().width() - width()) / 2;
int y = (pDesktopWidget->availableGeometry().height() - height()) / 2;
pAnimation->setDuration(1000);
pAnimation->setStartValue(QRect(x, 0, width(), height()));
pAnimation->setEndValue(QRect(x, y, width(), height()));
pAnimation->setEasingCurve(QEasingCurve::OutElastic);
pAnimation->start(QAbstractAnimation::DeleteWhenStopped);
}
抖動效果和透明效果
void MainWindow::onOpacityWindow()
{
QPropertyAnimation *pAnimation = new QPropertyAnimation(this, "windowOpacity");
pAnimation->setDuration(1000);
pAnimation->setKeyValueAt(0, 1);
pAnimation->setKeyValueAt(0.5, 0);
pAnimation->setKeyValueAt(1, 1);
pAnimation->start(QAbstractAnimation::DeleteWhenStopped);
}
void MainWindow::onShakeWindow()
{
QPropertyAnimation *pAnimation = new QPropertyAnimation(this, "pos");
pAnimation->setDuration(500);
pAnimation->setLoopCount(2);
pAnimation->setKeyValueAt(0, QPoint(geometry().x() - 3, geometry().y() - 3));
pAnimation->setKeyValueAt(0.1, QPoint(geometry().x() + 6, geometry().y() + 6));
pAnimation->setKeyValueAt(0.2, QPoint(geometry().x() - 6, geometry().y() + 6));
pAnimation->setKeyValueAt(0.3, QPoint(geometry().x() + 6, geometry().y() - 6));
pAnimation->setKeyValueAt(0.4, QPoint(geometry().x() - 6, geometry().y() - 6));
pAnimation->setKeyValueAt(0.5, QPoint(geometry().x() + 6, geometry().y() + 6));
pAnimation->setKeyValueAt(0.6, QPoint(geometry().x() - 6, geometry().y() + 6));
pAnimation->setKeyValueAt(0.7, QPoint(geometry().x() + 6, geometry().y() - 6));
pAnimation->setKeyValueAt(0.8, QPoint(geometry().x() - 6, geometry().y() - 6));
pAnimation->setKeyValueAt(0.9, QPoint(geometry().x() + 6, geometry().y() + 6));
pAnimation->setKeyValueAt(1, QPoint(geometry().x() - 3, geometry().y() - 3));
pAnimation->start(QAbstractAnimation::DeleteWhenStopped);
}