drawArc() 弧
drawChord() 弦
drawConvexPolygon() 凸多邊形
drawEllipse() 橢圓,注意橢圓是先整個框,然后逼近
drawImage() 圖像
drawLine() 線
drawLines() 多條線
drawPath()路徑; 想到哪就去哪,但是必須是直的
drawPicture() 按QPainter指令繪制 區分drawImage、drawPixmap
drawPie() 扇形
drawPixmap() 圖像
drawPoint() 點
drawPoints() 多個點
drawPolygon()多邊形
drawPolyline() 多折線
drawRect() 矩形
drawRects() 多個矩形
drawRoundRect() 圓角矩形
drawText() 文字
drawTiledPixmap() 平鋪圖像
drawLineSegments() 繪制折線
//1、窗口隱藏和顯示
//2、出窗口大小改變
//3、調用update()
//4、調用repaint()
Qt資料領取→「鏈接」
這里的扁平化指的是交互設計方面的一種風格。
扁平化是隨著極簡注意的風潮流行起來的,這個概念最核心的地方就是放棄一切裝飾效果,諸如陰影。透視,紋理,漸變等等能做出3D效果的元素一概不用。全部的元素的邊界都干凈利落,沒有不論什么羽化。漸變,或者陰影。從比較早的windows 8的Metro,
windows8
ios
android
都后面Android4.0的Holo Style,還有iOS7的“Ivy style” 的扁平化設計。
【領QT開發教程學習資料,點擊下方鏈接免費領取↓↓,先碼住不迷路~】
點擊→領取「鏈接」
那之后,感覺一切都被拍扁了。
今天從技術的角度來看看怎么讓Qt程序扁平化。
終于的效果是這種(一個圖片瀏覽器)
QWidget w;
w.show().
上面的代碼會生成一個Qt的Widget,然后顯示出來,這種窗體會帶上系統自帶的外框,也包括有最大化,最小化之類的按鈕,可是這種按鈕并非我們須要的style,并且我們也無法控制,所以我們須要自己實現右上角的窗體控制按鈕,創建一個pushbutton類,繼承自QPushButton。
pushbutton.h
#ifndef PUSHBUTTON_H
#define PUSHBUTTON_H
#include <QPushButton>
#include <QMouseEvent>
#include <QPainter>
#include <QDebug>
class PushButton : public QPushButton
{
Q_OBJECT
public:
PushButton(QWidget *parent=0);
~PushButton();
void loadPixmap(QString pic_name);
protected:
void enterEvent(QEvent *);
void leaveEvent(QEvent *);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *);
private:
enum ButtonStatus{NORMAL, ENTER, PRESS, NOSTATUS};
ButtonStatus status;
QPixmap pixmap;
int btn_width;
int btn_height;
bool isPressed;
};
#endif // PUSHBUTTON_H
【領QT開發教程學習資料,點擊下方鏈接免費領取↓↓,先碼住不迷路~】
點擊→領取「鏈接」
pushbutton.cpp
#include "pushbutton.h"
PushButton::PushButton(QWidget *parent)
:QPushButton(parent)
{
status=NORMAL;
isPressed=false;
}
PushButton::~PushButton()
{
}
void PushButton::loadPixmap(QString pic_name)
{
pixmap.load(pic_name);
//QSize picSize(96, 32);
pixmap=pixmap.scaledToHeight(30);
btn_width=pixmap.width()/3;
btn_height=pixmap.height();
setMinimumSize(btn_width, btn_height);
}
void PushButton::enterEvent(QEvent *)
{
status=ENTER;
update();
}
void PushButton::mousePressEvent(QMouseEvent *event)
{
if (event->button()==Qt::LeftButton)
{
isPressed=true;
status=PRESS;
update();
}
}
void PushButton::mouseReleaseEvent(QMouseEvent *)
{
if(isPressed)
{
isPressed=false;
status=ENTER;
update();
emit clicked();
}
}
void PushButton::leaveEvent(QEvent *)
{
status=NORMAL;
update();
}
void PushButton::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.drawPixmap(rect(), pixmap.copy(btn_width * status, 0, btn_width, btn_height));
}
須要準備一張button的圖片。包括button的各個狀態,依據button不同的狀態在paintEvent函數中繪制圖片不同的部分。
去除系統自帶的邊框僅僅須要一行代碼就能夠了。
setWindowFlags(Qt::FramelessWindowHint);
給widget加入投影的方法卡了我兩天。網上現存的有兩種方法,一種是先準備好一些陰影的圖片,然后手動在paintEvent中把陰影一個部分一個部分畫出來。
這個方案費時費力,不靈活,效果也不太好。
還有一種方法是stackoverflow上的,加入一個widget,把全部窗體控件放到這個widget中,給這個widget加入陰影效果,然后放在一個透明的widget上。這個我試了非常久,效果也不太好。
最后給出我的解決方法.
自己定義widget繼承自QWidget,構造函數中
this->setWindowFlags(Qt::FramelessWindowHint);
this->setAttribute(Qt::WA_TranslucentBackground);
用一個layout裝下全部控件,然后
#define SHADOW_WIDT 5
mainLayout->setContentsMargins(SHADOW_WIDTH, SHADOW_WIDTH, SHADOW_WIDTH, SHADOW_WIDTH);
this->setLayout(mainLayout);
在main.cpp中
MainWindow w;
QGraphicsDropShadowEffect *wndShadow=new QGraphicsDropShadowEffect;
wndShadow->setBlurRadius(5.0);
wndShadow->setOffset(0);
wndShadow->setColor(QColor("#017acc"));
w.setGraphicsEffect(wndShadow);
w.show();
效果還算完美^.
兩種方法。第一。使用QPalette
m_pMyWidget=new QWidget(this);
m_pMyWidget->setGeometry(0,0,300,100);
QPalette Pal(palette());
// set black background
Pal.setColor(QPalette::Background, Qt::black);
m_pMyWidget->setAutoFillBackground(true);
m_pMyWidget->setPalette(Pal);
m_pMyWidget->show();
另外一種,使用css
m_pMyWidget=new QWidget(this);
m_pMyWidget->setGeometry(0,0,300,100);
m_pMyWidget->setStyleSheet("background-color:black;");
m_pMyWidget->show();
就像用css來修飾Html一樣,css也能夠用來定義widget的樣式,Qt中使用樣式表的文檔能夠參考這里和這里。
注。不論什么自己定義繼承子QWidget的Widget,想要使用樣式表,都要手動實現paintevent函數,代碼例如以下:
void CustomWidget::paintEvent(QPaintEvent *)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
相比于使用Qt自帶的窗體管理,自己定義的扁平化窗體看上肯定高大上很多。但隨之而來的是開發成本和設計成本,由于全部的widget如今都須要自己管理(大小,顏色等),所以在開發之前一定要做好權衡。
21. 在對表格數據模型操作的時候,經常遇到一種場景就是,刪除某條記錄后,希望重新選中某一行。QTableView、QTableWidget本身就支持多選全選等操作,比如批量刪除可以多選。
//拿到表格數據模型
QAbstractItemModel *model=ui->tableView->model();
//主動定位到第三行
ui->tableView->setCurrentIndex(model->index(3, 0));
//主動定位到最后一行
ui->tableView->setCurrentIndex(model->index(model->rowCount() - 1, 0));
//設置選擇模式支持多選,其他幾個枚舉值自行查閱文檔。
ui->tableView->setSelectionMode(QAbstractItemView::MultiSelection);
//選擇全部
ui->tableView->selectAll();
//取消所有選中
ui->tableView->clearSelection();
//選中行,注意如果該行選中則執行后取消選中,如此往復。這個設計很巧妙,掌聲。
ui->tableView->selectRow(row);
//選中列,注意如果該列選中則執行后取消選中,如此往復。這個設計很巧妙,掌聲。
ui->tableView->selectColumn(column);
//獲取選中行的內容
QItemSelectionModel *selections=ui->tableView->selectionModel();
QModelIndexList selected=selections->selectedIndexes();
foreach (QModelIndex index, selected) {
qDebug() << index.row() << index.column() << index.data();
}
222. 在讀取文本文件的時候,有時候會發現讀取出來的中文亂碼,這個時候就需要識別文件編碼格式,然后主動設置對應的編碼去讀取就不會亂碼。
//檢查文件編碼 0=ANSI 1=UTF-16LE 2=UTF-16BE 3=UTF-8 4=UTF-8BOM
int DataCsv::findCode(const QString &fileName)
{
//假定默認編碼utf8
int code=3;
QFile file(fileName);
if (file.open(QIODevice::ReadOnly)) {
//讀取3字節用于判斷
QByteArray buffer=file.read(3);
quint8 b1=buffer.at(0);
quint8 b2=buffer.at(1);
quint8 b3=buffer.at(2);
if (b1==0xFF && b2==0xFE) {
code=1;
} else if (b1==0xFE && b2==0xFF) {
code=2;
} else if (b1==0xEF && b2==0xBB && b3==0xBF) {
code=4;
} else {
//嘗試用utf8轉換,如果可用字符數大于0,則表示是ansi編碼
QTextCodec::ConverterState state;
QTextCodec *codec=QTextCodec::codecForName("utf-8");
codec->toUnicode(buffer.constData(), buffer.size(), &state);
if (state.invalidChars > 0) {
code=0;
}
}
file.close();
}
return code;
}
223. 在連接遠程數據庫進行查詢數據的時候,有時候會發現很慢,尤其是表數據量越多越慢,本地的話同等數據量快很多,可以嘗試開啟只前進屬性,query.setForwardOnly(true);這樣的話只會緩存一次的數據,大大提高遠程數據庫的查詢效率,據說可以提高幾十倍百倍的速度。當然前提是對查詢的數據之前向前取數據的需求,如果還要往后取數據或者在數據模型QSqlQueryModel中使用,則不能開啟此屬性。原因在每次利用QSqlQuery獲取下一條記錄時,若不開啟isForwardOnly屬性(很遺憾默認就是不開啟),則每次都開辟新的內存空間,來存儲已經訪問及未訪問的記錄,這樣,每次都會浪費好多存儲空間。
224. Qt中的painter繪制非常靈活強大,接口豐富,但是對于很多初學者來說還是有一定的難度,尤其是各種奇奇怪怪的復雜格式,而這些格式用html確很好描述,比如控制行間距、字符間距等,此時可以用QTextDocument傳入html格式內容交給QPainter繪制,非常完美、簡單、強大,包括一些數學公式啥的。
void Form::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QTextDocument doc;
doc.setHtml(html);
//設置文本寬度
doc.setTextWidth(200);
//指定繪制區域
doc.drawContents(&painter, QRect(0, 0, 200, 70));
}
225. Qt中樣式表對選中顏色和懸停顏色是有優先級的,根據對操作系統默認樣式的觀察,當處于選中狀態+懸停狀態的時候,默認取懸停狀態,也就是鼠標移動到選中的列表item上,顏色取懸停狀態顏色。而Qt中如果兩種顏色都設置了,根據設置的順序來,取最后的為準,如果最后設置的選中狀態顏色,則當item處于選中狀態+懸停狀態的時候,取選中狀態顏色而不是懸停狀態顏色,切記!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。