一、前言
在音頻開發中,窗體多半為半透明、圓角窗體,如下為Qt 5.5 VS2013實現半透明方法總結。
二、半透明方法設置
1、窗體及子控件都設置為半透明
1)setWindowOpacity(0.8);//參數范圍為0-1.0,通過QSlider控件做成透明度控制條
2)無邊框設置
setWindowFlags(Qt::FramelessWindowHint);
3)窗體圓角設置
setAttribute(Qt::WA_TranslucentBackground);
通過paintEvent繪制窗體背景色與圓角
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing); // 反鋸齒;
painter.setBrush(QBrush(QColor("#616F76"))); //窗體背景色
painter.setPen(Qt::transparent);
QRect rect = this->rect(); //rect為繪制大小
rect.setWidth(rect.width() - 1);
rect.setHeight(rect.height() - 1);
painter.drawRoundedRect(rect, 15, 15); //15為圓角角度
//也可用QPainterPath 繪制代替 painter.drawRoundedRect(rect, 15, 15);
//QPainterPath painterPath;
//painterPath.addRoundedRect(rect, 15, 15);//15為圓角角度
//painter.drawPath(painterPath);
QWidget::paintEvent(event);
}
2、通過圖片貼圖,設置局部透明
1)窗體設置
setAttribute(Qt::WA_TranslucentBackground);//背景半透明屬性設置
setWindowFlags(Qt::FramelessWindowHint);//無邊框窗體設置
2)采用樣式加載圖片
ui->m_BgWidget->setStyleSheet("background-image:url(:/images/bg.png);");
注意:m_BgWidget為窗體對象的子窗體,不能直接設置QWidget
3)效果圖如下(錄制gif時刷新有點延時)
3、通過paintEvent重繪背景色透明度
1)窗體屬性設置
setAttribute(Qt::WA_TranslucentBackground);//背景半透明屬性設置
setWindowFlags(Qt::FramelessWindowHint);//無邊框窗體設置
m_BgColor = QColor("#616F76");//默認背景色
m_BgColor.setAlphaF(0.8);
this->setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)),
this, SLOT(showContextMenuSlot(const QPoint &)));//右擊出現菜單
2)右擊出現菜單
void Widget::showContextMenuSlot(const QPoint &pos)
{
QAction *act = NULL;
if(NULL == m_Menu)
{
m_Menu = new QMenu();//菜單
m_Actions.clear();//記錄所有Action
act = m_Menu->addAction("1.0", this, SLOT(funcSlot()));
m_Actions << act;
act->setCheckable(true);
act = m_Menu->addAction("0.8", this, SLOT(funcSlot()));
m_Actions << act;
act->setCheckable(true); //設置可選中
act->setChecked(true); //設置被選中
act = m_Menu->addAction("0.5", this, SLOT(funcSlot()));
m_Actions << act;
act->setCheckable(true);
act = m_Menu->addAction("0.3", this, SLOT(funcSlot()));
m_Actions << act;
act->setCheckable(true);
act = m_Menu->addAction("0.1", this, SLOT(funcSlot()));
m_Actions << act;
act->setCheckable(true);
}
m_Menu->exec(mapToGlobal(pos));//彈出菜單
}
3)選擇菜單Action,修改背景顏色透明度
void Widget::funcSlot()
{
QAction *act = qobject_cast<QAction *>(sender());//獲取選中的Action
if(act)
{
double alpha = act->text().toDouble();
m_BgColor.setAlphaF(alpha);//背景色透明度修改
foreach(QAction *action, m_Actions)//去除其余選中,互斥
{
if(act != action)
action->setChecked(false);
}
this->update();//刷新界面
}
}
4)通過paintEvent重繪背景色
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing); // 反鋸齒;
painter.setBrush(QBrush(m_BgColor));//修改后的背景色
painter.setPen(Qt::transparent);
QRect rect = this->rect(); //rect為繪制窗體大小
rect.setWidth(rect.width() - 1);
rect.setHeight(rect.height() - 1);
painter.drawRoundedRect(rect, 15, 15);//15為圓角角度
//也可用QPainterPath 繪制代替 painter.drawRoundedRect(rect, 15, 15);
//QPainterPath painterPath;
//painterPath.addRoundedRect(rect, 15, 15);
//painter.drawPath(painterPath);
QWidget::paintEvent(event);
}
5)效果如下(錄頻有點重影)
4、通過paintEvent采用Clear模式繪圖,實現局部透明
1)窗體屬性設置
m_Margin = 60;//各個繪制圖形與邊框的距離
m_BgColor = QColor("#00BFFF");//窗體背景色
installEventFilter(this);//事件過濾器,用於鼠標按下后界面移動
setWindowFlags(Qt::FramelessWindowHint);//無邊框窗體設置
setAttribute(Qt::WA_TranslucentBackground);//背景半透明屬性設置
2)畫筆屬性設置
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setPen(Qt::NoPen);
painter.setBrush(m_BgColor);
painter.drawRoundedRect(this->rect(), 15, 15);//設置整體窗體圓角為15°
painter.setCompositionMode(QPainter::CompositionMode_Clear);//設置Clear繪圖模式
//繪制三角形
drawTriangle(&painter);
//繪制圓
drawCircular(&painter);
//繪制矩形
drawRectangle(&painter);
}
3)繪制三角形
void Widget::drawTriangle(QPainter *painter)
{
QPainterPath path;
int width = this->width() / 2;
int height = this->height() / 2;
//頂點
int topX = width / 2;
int topY = m_Margin;
//左下頂點
int leftX = m_Margin;
int leftY = height - m_Margin;
//右下頂點
int rightX = width - m_Margin;
int rightY = height - m_Margin;
path.moveTo(topX, topY);//起點
path.lineTo(leftX, leftY);//畫線段1
path.lineTo(rightX, rightY);//畫線段2
path.lineTo(topX, topY);//畫線段3
painter->fillPath(path, QBrush(m_BgColor));//繪制三角形
}
4)繪制圓
void Widget::drawCircular(QPainter *painter)
{
int width = this->width() / 2;
int height = this->height() / 2;
int x = width + width / 2;//X向坐標
int y = height / 2; //Y向坐標
int r = width / 2 - m_Margin;
//第一個參數為中心點,r為x向、y向長度(不一致時可繪制橢圓)
painter->drawEllipse(QPoint(x, y), r, r);
}
5)繪制矩形
void Widget::drawRectangle(QPainter *painter)
{
int width = this->width() / 2;
int height = this->height() / 2;
int rectWidth = width - 2 * m_Margin;//矩形寬度
int rectHeight = height - 2 * m_Margin;//矩形高度
int rectX = width - rectWidth / 2;//矩形X向長度
int rectY = height + m_Margin;//矩形Y向長度
painter->drawRect(QRect(rectX, rectY, rectWidth, rectHeight));
}
6)運行效果