Как предотвратить увеличение QPushButton до размера длинного текстаPython

Программы на Python
Ответить
Anonymous
 Как предотвратить увеличение QPushButton до размера длинного текста

Сообщение Anonymous »

У меня есть QPushButton, ширину которого я хотел бы сохранить на уровне фиксированного процента от ширины его родительского HBoxLayout, чтобы он не увеличивался, когда его текст имеет очень длинный текст.
Изображение

Прямо сейчас, когда текст кнопки установлен на что-то очень длинное, кнопка расширяется, чтобы соответствовать этому длинному тексту, а также расширяет HBoxLayout и его предков до самого окна.
Изображение

Я планирую сделать собственный elide, используя QFontMetrics, чтобы попытаться создать текст с пропусками, соответствующий текущей ширине кнопки. Но я также хочу обработать случай, когда пользовательский результат elide немного шире, чем ожидалось: я не хочу, чтобы это приводило к увеличению ширины всего окна. Если текст слишком широкий, я бы предпочел просто обрезать его.
Итак: вот одна попытка, которая будет иметь смысл только в том случае, если размер окна не подлежит изменению:

Код: Выделить всё

self.ui.pushButton.setFixedWidth(self.ui.pushButton.width())
Добавление этой строки успешно предотвращает рост виджета — более длинный текст просто обрезается — но также делает виджет более узким:
Изображение

В конечном приложении у меня есть 2 метки и поле со списком в этом же HBoxLayout - Я также не хочу, чтобы их сжимали/уменьшали.
Вероятно, это связано с тем, что я не понимаю, как различные подсказки по размерам и политики размеров работают вместе. Возвращаясь к исходному вопросу, как правильно сделать эту кнопку с «принудительным закрытием» с ее «полной» «нормальной» шириной?
Ниже приведен код:
guiTest.py (код верхнего уровня):

Код: Выделить всё

from widthTest_ui import Ui_Dialog
from PyQt5.QtWidgets import QDialog,QApplication
import sys

class widthTestDialog(QDialog,Ui_Dialog):
def __init__(self,parent):
QDialog.__init__(self)
self.parent=parent
self.ui=Ui_Dialog()
self.ui.setupUi(self)
# self.ui.pushButton.setFixedWidth(self.ui.pushButton.width())
self.txt=''

def onClick(self,e):
self.txt+='a'
self.ui.pushButton.setText(self.txt)

def main():
app = QApplication(sys.argv)
global w # so that eFilter can call methods of the top level widget
w = widthTestDialog(app)
w.show()
sys.exit(app.exec_())

if __name__ == "__main__":
main()
widthTest_ui.py — из pyuic5:

Код: Выделить всё

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(176, 87)
self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.pushButton = QtWidgets.QPushButton(Dialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth())
self.pushButton.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setFamily("Segoe UI")
font.setPointSize(12)
self.pushButton.setFont(font)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
self.verticalLayout.addLayout(self.horizontalLayout)

self.retranslateUi(Dialog)
self.pushButton.clicked.connect(Dialog.onClick) # type: ignore
QtCore.QMetaObject.connectSlotsByName(Dialog)

def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.pushButton.setText(_translate("Dialog", "PushButton"))
ОБНОВЛЕНИЕ на основе комментариев:
Как было предложено, раскомментирование этой строки в init и использование sizeHint работает — виджет заполняет «первоначально ожидаемую» ширину и не увеличивается по мере того, как текст становится слишком длинным:

Код: Выделить всё

self.ui.pushButton.setFixedWidth(self.ui.pushButton.sizeHint().width())
ПРИМЕЧАНИЕ: завершает ответ на первоначальный вопрос; опубликую это как ответ; часть вопроса, приведенная ниже, на самом деле просто «становится жадной» и расширяет объем первоначального вопроса, поэтому ее не нужно рассматривать здесь. Чтобы избежать этого, я бы запретил изменение размера окна.

Теперь я хотел бы посмотреть, смогу ли я повторно применить эту логику при изменении размера окна: по мере роста окна виджет увеличивается пропорционально, но затем остается там с той же логикой фиксированной ширины. Похоже, вам нужно будет «освободить» фиксированный размер, чтобы позволить ему изменять размер пропорционально, как обычно, а затем снова исправить размер, когда изменение размера будет выполнено. Я надеялся, что это поможет, но, увы, к моменту запуска resizeEvent уже слишком поздно:

Код: Выделить всё

def resizeEvent(self,e):
print('resized')
self.ui.pushButton.setMinimumSize(0,0)
self.ui.pushButton.setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)
self.ui.pushButton.setFixedWidth(self.ui.pushButton.sizeHint().width())

Вероятно, есть способ добиться этого, обрабатывая нажатие мыши на край окна до того, как произойдет изменение размера, но это звучит немного неясно и хаотично. Интересно, есть ли лучший способ достичь общей цели - может быть, просто использовать более строгую пользовательскую логику elide и не пытаться использовать setFixedWidth.

Подробнее здесь: https://stackoverflow.com/questions/797 ... -long-text
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»