最近專案中需要實現一個訊息推送的功能,模仿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,還不知道問題出在哪。