Найти - Пользователи
Полная версия: PyQt4, создание imagebutton
Начало » GUI » PyQt4, создание imagebutton
1
Guljaca
Как создать изображение-кнопку с двумя состояниями:
Ждущий режим (одно изображение)
Клик (второе изображение/подсветка)

Растянуть изображение по размеру кнопки

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]))

Осталось только как-то текст поверх всего вывести
Если использовать label - он перекрывает кнопку
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()
reclosedev
Я бы через 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_()
А вместо time.sleep и processEvents в данном случае лучше таймер, так отзывчевей интерфейс будет.

Здесь только нужно добавить чтобы пути до картинок настраиваемыми были и кнопку нужно ресайзить под размер картинки.
Guljaca
reclosedev
Я бы через background-image сделал:
Плохо сочетается с png с прозрачным фоном (ванильный экран вместо прозрачности) + проигрывается анимация самого нажатия, что с двумя изображениями лишнее.
Хотя, можно применять их вместе, но лучше бы получить все в одном
reclosedev
Тогда есть вариант наследоваться от QAbstractButton, переопределить paintEvent, в котором сначала рисовать pixmap, а на нем текст.

Guljaca
Можешь набросать пример?

Что в этой части описано?
def __init__(self, parent=None, *args, **kwargs):
        super(ImageButton, self).__init__(parent, *args, **kwargs)
Почему текст присваивается так, а не widget._change_image(“test”)?
widget = ImageButton("test")
reclosedev
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)
http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qt_properties.html
http://blog.odnous.net/2011/06/frequently-overlooked-and-practical.html

Guljaca
Почему текст присваивается так, а не widget._change_image(“test”)?
_change_image был задуман для смены картинки, для текста есть setText()
Guljaca
Поработал с примером и нашел недостатки:
1 - если промотать ползунком, изображения ‘клонируются’. Восстанавливаются только, если навести над ними курсор. Если видна только часть области - изображение сжимается до размеров этой облости
2 - так и не удалось задать максимальный размер. В grid и hbox кнопки растягиваются
3 - при блокировки кнопки с помощью self.button.setDisabled(False) - серым окрашивается только текст.

class ImageButton(QtGui.QPushButton):
Можно убрать фон с первого изображения, добавив self.setFlat(True), однако анимация остается (а с ней и ванильный фон при клике появляется) и цветовой канал при блокировки кнопки с помощью self.button.setDisabled(False) не меняется.


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

Как вариант - можно ли вывести изображение под текстом в HTML?
reclosedev
Guljaca
1 - если промотать ползунком, изображения ‘клонируются’. Восстанавливаются только, если навести над ними курсор. Если видна только часть области - изображение сжимается до размеров этой облости
Воспроизвести не удалось, возможно нужно заменить event.rect() на self.rect()
painter.drawPixmap(self.rect(), self._pixmap)

Guljaca
- так и не удалось задать максимальный размер. В grid и hbox кнопки растягиваются
Попробовал
button.setMaximumSize(width, height)
ничего не растягивается.

Guljaca
class ImageButton(QtGui.QPushButton):
QAbstractButton же. Или это еще один вариант?



Guljaca
reclosedev
Воспроизвести не удалось, возможно нужно заменить event.rect() на self.rect()
Ок, все работает, спасибо!

This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB