關於QComboBox內核是如何實現的,原理是如何的,分析如下:
QComboBox是繼承自QWidget重寫的窗口,的111區是用QLineEdit實現的,源碼如下:
QLineEdit *lineEdit() const;
2區是用一個類似於toolbutton做出來的,可以出發下拉事件和更改圖標
2區出發事件會彈出一個關聯的ListView窗口,系統內核會彈出與該窗口關聯的類似於qlistview,該關聯的qlistview使用的是model-view-delegate結構,
該listview響應響應的事件,處理好和111,2區關聯的數據處理既可以出來
所以QComboBox可以做到自由變換到各種形狀,比如圓角矩形等不規則圖形,她的lineEdit組件也是可以替換的,從源碼可以看出它是刪除原先的默認的lineEdit,然後換上新的LineEdit,源碼如下:
void QComboBox::setLineEdit(QLineEdit *edit)
{
。。。
if (edit == d->lineEdit)
return;
edit->setText(currentText());
delete d->lineEdit;
d->lineEdit = edit;
。。。
}
它的關聯的listview原理也是差不多的,所以可以自由的變換,而且獨立的變換,
這個可能是個bug
auto aaa = new QListView();
m_pComboBox->setView(aaa);
aaa->setStyleSheet("QAbstractItemView::item{height:35px;}");這樣設置,item的高度是可以設置成功的,
但是這樣就是不行,其實它的邏輯意思應該是一樣的,都是修改視圖
m_pComboBox->view()->setStyleSheet("QAbstractItemView::item{height:35px;}");
如果需要做ui更加複雜多變的,可以重寫一個listview,只要是listview可以做到的效果,QComboBox都是可以做到的。
由於與QComboBox相關聯的listview應該是獨立的,可以自由繪製需要的效果,但是還是有一定的關聯的,當設置窗口爲圓角矩形時候,一般根據面向對象的想法,應該是設置起對應的listview爲圓角矩形就可以了,但是效果並不是特別理想,比如以下代碼:
m_pComboBox->view()->window()->setWindowFlags(Qt::Popup | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint);
m_pComboBox->view()->window()->setAttribute(Qt::WA_TranslucentBackground);
m_pComboBox->view()->setStyleSheet(R"(
QAbstractItemView {
border-radius: 14px ;
background-color:rgb(134,134,134);
}
)");
實現效果達到了圓角矩形,但是會有陰影,但是代碼裏面已經NoDropShadowWindowHint,去掉了陰影,所以這裏有點感覺不太合乎邏輯,如果把代碼改爲 m_pComboBox/*->view()*/->setStyleSheet(R"(
QAbstractItemView {
border-radius: 14px ;
background-color:rgb(134,134,134);
}
就是可以達到需要的效果的,不會再有陰影了,因爲已經去掉了,是合乎邏輯的。
大致猜一下它底層的實現可能是,在使用其中的內部的view的stylesheet的時候,底層執行的繪製函數只是其對應的listview,但是這個 NoDropShadowWindowHint底層應該是需要和父類QComboBox產生關聯的,所以會導致有些繪製動作沒有生效,因爲沒有執行到其父類有些關聯的動作,所以會導致NoDropShadowWindowHint沒有生效,所以說Qt有自己的一個規則,套路,所以在QComboBox這方面如果需要繪製的話,不要使用它對應的基本已經封裝的子窗口,需要繪製的話,儘量使用QComboBox類自身,就不會出現這樣類似的問題了