Qt-Qlabel 自定義滑鼠點選事件以及文字樣式效果設計
最近專案中需要實現一個訊息推送的功能,模仿QQ訊息彈窗的方式實現,介面開發的工具為Qt。對桌面應用開發這塊不太熟悉,通過摸索嘗試也算是把這個功能實現了,其中也碰到了一些比較麻煩的問題,這些問題我看也具有一定的普遍性,就把我摸索出來的解決方法和大家分享下(可能有更好的方法我沒想到)!
Qt雖說支援CSS2的所有樣式效果,但真正實現起來可並不如html那般簡單。這個訊息彈窗中的文字連結以及點選效果的設定就把我折騰了好久。需要設計的效果是:
1、標題、內容以及圖片均具有點選的效果;
2、滑鼠放置在標題和內容上,文字變色並且高亮顯示,無需下劃線;
3、滑鼠的形狀:在放置在標題和內容上時由箭頭變成小手指。
整個窗體採用QWidget型別,標題、內容、圖片採用QLabel型別。當我實現文字點選時,發現QLabel沒有像button那樣的clicked訊號,網上推薦瞭如下兩種方法:
1、在標題中嵌入html標籤:
QString title = "<a href=' " + url + " '>" + content + " </a>
ui.Title->setText(title)
setOpenExternalLinks(true) // 允許開啟外部連結,這個可在ui檔案中通過視覺化工具設定(我用的是VS外掛Qt設計師)
但這種方式存在兩個個問題:1)無法支援滑鼠hover效果;2)它會繼承html超連結的內部樣式:blue underline。
我試圖在qss檔案中設定樣式,但無法改變其內建樣式。也可以在a標籤中直接設定style樣式,但這隻能解決第二個問題。
2、自定義實現QLabel以及clicked 訊號,然後通過qss設定QLabel的文字樣式以及hover效果:
1)自定義QLabel:
class ActivityLabel : public QLabel
{
Q_OBJECT
public:
ActivityLabel(QWidget * parent = 0);
~ActivityLabel(void);
protected:
void mouseReleaseEvent(QMouseEvent * ev);
signals:
void clicked();
};
void ActivitiLabel::mouseReleaseEvent(QMouseEvent * ev) {//定義滑鼠左鍵點選事件 if(ev->button() == Qt::LeftButton) { Q_UNUSED(ev) emit clicked(); } }
並將ui檔案中的控制元件型別設定為自定義的QLabel型別,這樣就解決QLabel不支援clicked事件的問題。
2)在qss中設定title的文字樣式和hover效果
QLabel#Title
{
background-image: url(:/ActivitiForm/Resources/act_content_bg.png);
font: bold 13px "微軟雅黑";
color: black;
}
QLabel#Title:hover
{
color:blue;
}
3)定義與clicked訊號對應的槽:
void ActivitiForm::onDetailClicked()
{
QUrl url(activiti->getPageLink());
QDesktopServices::openUrl(url);
}
connect(ui.Title,SIGNAL(clicked()),this,SLOT(onDetailClicked()));
4)設定QLabel控制元件的滑鼠形狀:
Title->setCursor(QCursor(Qt::PointingHandCursor));
或者通過qt設計師設定:
5)設定自動換行顯示:
ui.Content->setText(content);
ui.Content->adjustSize();
注意這兩條程式碼的順序。
除了換行,我們還需要設定Content框的大小:長的大小固定,寬可以任何調整,具體設定如下:
QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Preferred);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(20);
sizePolicy1.setHeightForWidth(Content->sizePolicy().hasHeightForWidth());
Content->setSizePolicy(sizePolicy1);
Content->setMinimumSize(QSize(121, 0));
Content->setMaximumSize(QSize(121, 90));
6)QLabel中中文亂碼的處理:
QByteArray content = reply_->readAll(); //讀取網路位元組流
QTextCodec *codec = QTextCodec::codecForLocale(); //將編碼方式設定成本地編碼方式
QString contentQStr = codec->toUnicode(content); //使用編碼器進行轉碼
注:當時有將codec強行設定成gbk的編碼方式,但程式執行後發現bug,還不知道問題出在哪。