2010-06-16 13 views
10

Birkaç QT widget'ı içeren bir formun içinde bir QTextEdit widget'ı kullanmaya çalışıyorum. Formun kendisi bir pencere için merkezi pencere öğesi olan bir QScrollArea'nın içinde yer alır. Amacım, gerekli herhangi bir kaydırmanın ana QScrollArea'da (herhangi bir pencere öğesi yerine) yer alacağı ve içerideki herhangi bir pencere öğesi, içeriklerini tutmak için yüksekliklerini otomatik olarak yeniden boyutlandıracak olmasıdır.QT'nin QTextEdit'in Metne Göre Eşleştirilmesi Yüksekliği: maximumViewportSize()

QTextEdit ile yüksekliğin otomatik olarak yeniden boyutlandırılmasını uygulamayı denedim, ancak garip bir sorunla karşılaştım. Ben QTextEdit bir alt sınıfını yarattı ve bunun gibi sizeHint() reimplemented:

QSize OperationEditor::sizeHint() const { 
    QSize sizehint = QTextBrowser::sizeHint(); 
    sizehint.setHeight(this->fitted_height); 
    return sizehint; 
} 

this-> QTextEdit yönettiği "contentsChanged()" sinyaline kablolu bu slot üzerinden yukarı güncel tutulur fitted_height:

this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); 

Ben this post.

okuduktan sonra bu yaklaşımı aldı:

void OperationEditor::fitHeightToDocument() { 
     this->document()->setTextWidth(this->viewport()->width()); 
     QSize document_size(this->document()->size().toSize()); 
     this->fitted_height = document_size.height(); 
     this->updateGeometry(); 
} 

QTextEdit alt sınıfın büyüklüğü politikasıdır

İşte benim problem: sizeHint döndü ne yükseklik olursa olsun, QTextEdit olarak

giderek daha büyük alma durur, pencere doldurmak için boyutlandırır ve QTextEdit içinde hareket etmeye başlar(). Eğer başlangıçta sizeHint() büyük bir sabit sayı döndürürse, QTextEdit çok büyüktür ve beklendiği gibi dış QScrollArea'nın içinde güzel bir şekilde yer alır. Ancak, sizeHint yavaş yavaş QTextEdit boyutunu büyük ölçüde başlatmak için çok büyük yapmak yerine, o zaman geçerli pencere doldurur ve büyüyen yerine kaydırma başlar zaman dışarı ayarlar.

SizeHint() öğesinin ne döndüğü önemli değil, QTextEdit değerini, QAbstractScrollArea öğesinden devralınan maximumViewportSize() 'den döndürülen değerden daha büyük bir şekilde yeniden boyutlandırmayacak şekilde bu sorunu takip ettim. Bunun, viewport() -> maximumSize() ile aynı sayı olmadığını unutmayın. Bu değeri nasıl ayarlayacağımı anlayamıyorum.

QT'nin kaynak koduna bakıldığında, maximumViewportSize(), "kaydırma çubuklarının geçerli bir kaydırma aralığı içermiyormuş gibi, görünümün boyutunu döndürüyor." Bu değer temel olarak, küçük resim eksi (2 * frameWidth + kenar boşlukları) artı herhangi bir kaydırma çubuğu genişliği/yüksekliğinin geçerli boyutu olarak hesaplanır. Bu bana pek bir şey ifade etmiyor, ve bu numaranın neden alt sınıfın sizeHint() uygulamasının üstesinden gelebilecek bir şekilde kullanıldığını açık bir şekilde göremiyorum. Ayrıca, tek "frameWidth" tam sayısının hem genişlik hem de yükseklik hesaplamasında kullanılması garip görünüyor.

Bu konuda biraz ışık tutabilir misiniz? QT'nin düzen motoru hakkındaki zayıf anlayışımın burada suçlandığından şüpheleniyorum.

Düzenleme: önce bunu yükledikten sonra, size aynı boyutta sizeHint() döndürmek için maximumViewportSize() öğesini yeniden kullanma fikrim vardı. Maalesef, hala aynı problemi yaşadığım için işe yaramadı.

cevap

8

Bu sorunu çözdüm.Ben işe almak için yapmak zorunda 2 şey vardı:

  1. Widget hiyerarşisini yukarı yürümek ve sağlamak için mantıklı tüm boyut politikaları emin olun herhangi bir çocuk Widget küçük/büyük olmak istiyorsa, daha sonra ana widget aynı şey olmak isterdi.

  2. Bu, düzeltmenin ana kaynağıdır. QTextEdit'in bir QScrollArea öğesindeki ana parçacık olan bir QFrame içinde olması nedeniyle QScrollArea'nın, "widgetResizable" özelliği true olmadıkça, dahili parçacığı yeniden boyutlandırmayacağı bir kısıtlaması olduğu ortaya çıkıyor. Bunun için belgeler: http://doc.qt.io/qt-4.8/qscrollarea.html#widgetResizable-prop. Bu ayar ile uğraşana ve işe koyuluncaya kadar belgeler açık değildi. Dokümanlardan, bu özellik sadece ana kaydırma alanının bir widget'i (örn. Ebeveynten çocuğa) yeniden boyutlandırmak istediği zamanlarla ilgileniyor gibi görünüyor. Aslında, kaydırma alanındaki ana pencere öğesi yeniden boyutlandırmak istiyorsa (ör. Çocuktan ebeveyne), bu ayarın doğru olarak ayarlanması gerektiği anlamına gelir.

Yani, hikayenin ruhu QTextEdit kodu sizeHint geçersiz kılma doğru olduğunu, ancak QScrollArea ana çerçevenin sizeHint döndü değerini görmezden edildi.

Yay! İşe yarıyor!

+0

Bunu bulmak için teşekkürler. Kesinlikle bir sonra bana yardım edecek. –

+2

Aaron, çözümünüz üzerinde durabilir mi? QTextEdit ile ilişkili bir QScrollArea'ya erişemiyorum. WidgetResizable özelliğini ayarladığınız bir QTextEdit verilen açıklayabilir misiniz? yani nasıl bağlandıkları? QTextEdit aslında setWidgetResizable özelliği olmayan QAbstractScrollArea türetilmiştir (Qt 4.7'deyim). Teşekkürler bu gerçekten beni rahatsız ediyor! – Dave

+0

@supertwang cevabımı benzer bir soruya kontrol etmek isteyebilirsiniz [here] (http://stackoverflow.com/questions/11851020/a-qwidget-like-qtextedit-that-wraps-its-height-automatically-to- onun-içerikleri/13599165 # 13599165). – laurasia

0

Düzenin büyütülüp zorlanmayacağını görmek için QTextEdit'un minimumSize özelliğini ayarlamayı deneyebilirsiniz.

Qt düzen planının çoğunu anlamıyorum, ancak minimum ve maksimum boyutu ayarlamak, benim yapmak istediğim şeyi yapmak. Eh, çoğu zaman zaten.

+0

Cevabınız için teşekkürler, Stephen. Her bir minimalSize, maximumSize ve fixedSize kombinasyonunu (ilgili QSizePolicy'larla) ayarlamayı denedim, ancak hiçbiri bir fark yaratmadı. – Aaron

İlgili konular