Форум сайта python.su
Как создать изображение-кнопку с двумя состояниями:
Ждущий режим (одно изображение)
Клик (второе изображение/подсветка)
Растянуть изображение по размеру кнопки
from PyQt4.QtGui import * from PyQt4.QtCore import * class ExtendedQLabel(QLabel): def __init(self, parent): Label.__init__(self, parent) def mouseReleaseEvent(self, ev): self.emit(SIGNAL('clicked()')) # Часть скрипта с созданием кнопки self.button[key] = ExtendedQLabel(self) self.button[key].setMaximumSize(150,150) self.button[key].setPixmap(QPixmap(item[key].img)) self.connect(self.button[key], SIGNAL('clicked()'), functools.partial(use, [key,self.nameMenu]))
from PyQt4.QtGui import * from PyQt4.QtCore import * import imageop, sys, os, random, codecs, functools, sip,time # Делает возможным создавить imagebutton class ExtendedQLabel(QLabel): def __init(self, parent): QLabel.__init__(self, parent) def mouseReleaseEvent(self, ev): self.emit(SIGNAL('clicked()')) class MainUI(QWidget): BUTTON_IMAGE = 'button1.png' def __init__(self, *args): apply(QWidget.__init__,(self, ) + args) QWidget.__init__(self) self.resize(300, 100) self.label = QLabel() self.initButton() def initButton(self): self.label.setText('Button') self.ImageButton = ExtendedQLabel(self) self.ImageButton.move(0,0) self.ImageButton.setPixmap(QPixmap(self.BUTTON_IMAGE)) self.ImageButton.connect(self.ImageButton, SIGNAL('clicked()'), self.buttonClicked) def buttonClicked(self): self.ImageButton.setPixmap(QPixmap('button2.png')) QApplication.processEvents() time.sleep(0.3) self.ImageButton.setPixmap(QPixmap('button1.png')) print('Button Clicked') if __name__ == '__main__': app = QApplication(sys.argv) win = MainUI() win.show() app.exec_() sys.exit()
Отредактировано Guljaca (Окт. 8, 2012 20:31:45)
Офлайн
Я бы через background-image сделал:
import time from PyQt4 import QtCore, QtGui class ImageButton(QtGui.QPushButton): def __init__(self, parent=None, *args, **kwargs): super(ImageButton, self).__init__(parent, *args, **kwargs) self._change_image('image1.png') self.clicked.connect(self._on_click) def _on_click(self): self._change_image('image2.png') QtCore.QTimer.singleShot(300, lambda : self._change_image('image1.png')) def _change_image(self, path): self.setStyleSheet('''background-image: url("%s"); background-repeat:no-repeat;''' % path) app = QtGui.QApplication([]) widget = ImageButton("test") widget.show() app.exec_()
Офлайн
reclosedevПлохо сочетается с png с прозрачным фоном (ванильный экран вместо прозрачности) + проигрывается анимация самого нажатия, что с двумя изображениями лишнее.
Я бы через background-image сделал:
Отредактировано Guljaca (Окт. 9, 2012 22:05:27)
Офлайн
Тогда есть вариант наследоваться от QAbstractButton, переопределить paintEvent, в котором сначала рисовать pixmap, а на нем текст.
Офлайн
Можешь набросать пример?
Что в этой части описано?
def __init__(self, parent=None, *args, **kwargs): super(ImageButton, self).__init__(parent, *args, **kwargs)
widget = ImageButton("test")
Офлайн
GuljacaПриближенно:
Можешь набросать пример?
from PyQt4 import QtCore, QtGui class ImageButton(QtGui.QAbstractButton): def __init__(self, image1, image2, parent=None, *args, **kwargs): super(ImageButton, self).__init__(parent, *args, **kwargs) self._pixmap1 = QtGui.QPixmap(image1) self._pixmap2 = QtGui.QPixmap(image2) self._pixmap = self._pixmap1 self.clicked.connect(self._on_click) def _on_click(self): self.set_pixmap(self._pixmap2) QtCore.QTimer.singleShot(300, lambda : self.set_pixmap(self._pixmap1)) def paintEvent(self, event): painter = QtGui.QPainter(self) painter.drawPixmap(event.rect(), self._pixmap) painter.drawText(self.rect(), QtCore.Qt.AlignCenter, self.text()); def set_pixmap(self, pixmap): self._pixmap = pixmap self.update() def sizeHint(self): return self._pixmap.size() app = QtGui.QApplication([]) widget = ImageButton("image1.png", "image2.png", text="test") widget.show() app.exec_()
GuljacaВызываем базовый конструктор, чтобы была возможность задать разные свойства и соединять сигналы при создании.
Что в этой части описано?
button = QtGui.QPushButton(clicked=on_click, text='My button', checkable=True)
Guljaca_change_image был задуман для смены картинки, для текста есть setText()
Почему текст присваивается так, а не widget._change_image(“test”)?
Офлайн
Поработал с примером и нашел недостатки:
1 - если промотать ползунком, изображения ‘клонируются’. Восстанавливаются только, если навести над ними курсор. Если видна только часть области - изображение сжимается до размеров этой облости
2 - так и не удалось задать максимальный размер. В grid и hbox кнопки растягиваются
3 - при блокировки кнопки с помощью self.button.setDisabled(False) - серым окрашивается только текст.
class ImageButton(QtGui.QPushButton):
Можно убрать фон с первого изображения, добавив self.setFlat(True), однако анимация остается (а с ней и ванильный фон при клике появляется) и цветовой канал при блокировки кнопки с помощью self.button.setDisabled(False) не меняется.
Пока годится только мой вариант, но для него надо вручную создавать все надписи для кнопок. В остальных главная проблема - масштабирование.
Как вариант - можно ли вывести изображение под текстом в HTML?
Отредактировано Guljaca (Окт. 11, 2012 17:29:45)
Офлайн
GuljacaВоспроизвести не удалось, возможно нужно заменить event.rect() на self.rect()
1 - если промотать ползунком, изображения ‘клонируются’. Восстанавливаются только, если навести над ними курсор. Если видна только часть области - изображение сжимается до размеров этой облости
painter.drawPixmap(self.rect(), self._pixmap)
GuljacaПопробовал
- так и не удалось задать максимальный размер. В grid и hbox кнопки растягиваются
button.setMaximumSize(width, height)
GuljacaQAbstractButton же. Или это еще один вариант?
class ImageButton(QtGui.QPushButton):
Офлайн
reclosedevОк, все работает, спасибо!
Воспроизвести не удалось, возможно нужно заменить event.rect() на self.rect()
Отредактировано Guljaca (Окт. 21, 2012 18:12:22)
Офлайн