#!/usr/bin/env python ############################################################################# ## ## Copyright (C) 2005-2005 Trolltech AS. All rights reserved. ## ## This file is part of the example classes of the Qt Toolkit. ## ## This file may be used under the terms of the GNU General Public ## License version 2.0 as published by the Free Software Foundation ## and appearing in the file LICENSE.GPL included in the packaging of ## this file. Please review the following information to ensure GNU ## General Public Licensing requirements will be met: ## http://www.trolltech.com/products/qt/opensource.html ## ## If you are unsure which license is appropriate for your use, please ## review the following information: ## http://www.trolltech.com/products/qt/licensing.html or contact the ## sales department at sales@trolltech.com. ## ## This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ## WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ## ############################################################################# import sys from PyQt4 import QtCore, QtGui class IconSizeSpinBox(QtGui.QSpinBox): def valueFromText(self, text): regExp = QtCore.QRegExp(self.tr("(\\d+)(\\s*[xx]\\s*\\d+)?")) if regExp.exactMatch(text): return regExp.cap(1).toInt() else: return 0 def textFromValue(self, value): return self.tr("%1 x %1").arg(value) class ImageDelegate(QtGui.QItemDelegate): def createEditor(self, parent, option, index): comboBox = QtGui.QComboBox(parent) if index.column() == 1: comboBox.addItem(self.tr("Normal")) comboBox.addItem(self.tr("Active")) comboBox.addItem(self.tr("Disabled")) elif index.column() == 2: comboBox.addItem(self.tr("Off")) comboBox.addItem(self.tr("On")) self.connect(comboBox, QtCore.SIGNAL("activated(int)"), self.emitCommitData) return comboBox def setEditorData(self, editor, index): comboBox = editor if not comboBox: return pos = comboBox.findText(index.model().data(index).toString(), QtCore.Qt.MatchExactly) comboBox.setCurrentIndex(pos) def setModelData(self, editor, model, index): comboBox = editor if not comboBox: return model.setData(index, QtCore.QVariant(comboBox.currentText())) def emitCommitData(self): self.emit(QtCore.SIGNAL("commitData(QWidget *)"), self.sender()) class IconPreviewArea(QtGui.QWidget): NumModes = 3 NumStates = 2 def __init__(self, parent = None): QtGui.QWidget.__init__(self, parent) mainLayout = QtGui.QGridLayout() self.setLayout(mainLayout) self.icon = QtGui.QIcon() self.size = QtCore.QSize() self.stateLabels = [] self.modeLabels = [] self.pixmapLabels = [] self.stateLabels.append(self.createHeaderLabel(self.tr("Off"))) self.stateLabels.append(self.createHeaderLabel(self.tr("On"))) self.modeLabels.append(self.createHeaderLabel(self.tr("Normal"))) self.modeLabels.append(self.createHeaderLabel(self.tr("Active"))) self.modeLabels.append(self.createHeaderLabel(self.tr("Disabled"))) for j in range(IconPreviewArea.NumStates): mainLayout.addWidget(self.stateLabels[j], j + 1, 0) for i in range(IconPreviewArea.NumModes): mainLayout.addWidget(self.modeLabels[i], 0, i + 1) self.pixmapLabels.append([]) for j in range(IconPreviewArea.NumStates): self.pixmapLabels[i].append(self.createPixmapLabel()) mainLayout.addWidget(self.pixmapLabels[i][j], j + 1, i + 1) def setIcon(self, icon): self.icon = icon self.updatePixmapLabels() def setSize(self, size): if size != self.size: self.size = size self.updatePixmapLabels() def createHeaderLabel(self, text): label = QtGui.QLabel(self.tr("%1").arg(text)) label.setAlignment(QtCore.Qt.AlignCenter) return label def createPixmapLabel(self): label = QtGui.QLabel() label.setEnabled(False) label.setAlignment(QtCore.Qt.AlignCenter) label.setFrameShape(QtGui.QFrame.Box) label.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) label.setBackgroundRole(QtGui.QPalette.Base) label.setMinimumSize(132, 132) return label def updatePixmapLabels(self): for i in range(IconPreviewArea.NumModes): if i == 0: mode = QtGui.QIcon.Normal elif i == 1: mode = QtGui.QIcon.Active else: mode = QtGui.QIcon.Disabled for j in range(IconPreviewArea.NumStates): state = {True: QtGui.QIcon.Off, False: QtGui.QIcon.On}[j == 0] pixmap = self.icon.pixmap(self.size, mode, state) self.pixmapLabels[i][j].setPixmap(pixmap) self.pixmapLabels[i][j].setEnabled(not pixmap.isNull()) class MainWindow(QtGui.QMainWindow): def __init__(self, parent = None): QtGui.QMainWindow.__init__(self, parent) self.centralWidget = QtGui.QWidget() self.setCentralWidget(self.centralWidget) self.createPreviewGroupBox() self.createImagesGroupBox() self.createIconSizeGroupBox() self.createActions() self.createMenus() self.createContextMenu() mainLayout = QtGui.QGridLayout() mainLayout.addWidget(self.imagesGroupBox, 0, 0) mainLayout.addWidget(self.iconSizeGroupBox, 1, 0) mainLayout.addWidget(self.previewGroupBox, 0, 1, 2, 1) self.centralWidget.setLayout(mainLayout) self.setWindowTitle(self.tr("Icons")) self.checkCurrentStyle() self.otherRadioButton.click() self.resize(860, 400) def about(self): QtGui.QMessageBox.about(self, self.tr("About Icons"), self.tr( "The Icons example illustrates how Qt renders an icon in " "different modes (active, normal, and disabled) and states (on " "and off) based on a set of images.")) def changeStyle(self, checked): if not checked: return action = self.sender() style = QtGui.QStyleFactory.create(action.data().toString()) QtGui.QApplication.setStyle(style) self.smallRadioButton.setText(self.tr("Small (%1 x %1)") .arg(style.pixelMetric(QtGui.QStyle.PM_SmallIconSize))) self.largeRadioButton.setText(self.tr("Large (%1 x %1)") .arg(style.pixelMetric(QtGui.QStyle.PM_LargeIconSize))) self.toolBarRadioButton.setText(self.tr("Toolbars (%1 x %1)") .arg(style.pixelMetric(QtGui.QStyle.PM_ToolBarIconSize))) self.listViewRadioButton.setText(self.tr("List views (%1 x %1)") .arg(style.pixelMetric(QtGui.QStyle.PM_ListViewIconSize))) self.iconViewRadioButton.setText(self.tr("Icon views (%1 x %1)") .arg(style.pixelMetric(QtGui.QStyle.PM_IconViewIconSize))) self.changeSize() def changeSize(self): if self.otherRadioButton.isChecked(): extent = self.otherSpinBox.value() else: if self.smallRadioButton.isChecked(): metric = QtGui.QStyle.PM_SmallIconSize elif self.largeRadioButton.isChecked(): metric = QtGui.QStyle.PM_LargeIconSize elif self.toolBarRadioButton.isChecked(): metric = QtGui.QStyle.PM_ToolBarIconSize elif self.listViewRadioButton.isChecked(): metric = QtGui.QStyle.PM_ListViewIconSize else: metric = QtGui.QStyle.PM_IconViewIconSize extent = QtGui.QApplication.style().pixelMetric(metric) self.previewArea.setSize(QtCore.QSize(extent, extent)) self.otherSpinBox.setEnabled(self.otherRadioButton.isChecked()) def changeIcon(self): icon = QtGui.QIcon() for row in range(self.imagesTable.rowCount()): item0 = self.imagesTable.item(row, 0) item1 = self.imagesTable.item(row, 1) item2 = self.imagesTable.item(row, 2) if item0.checkState() == QtCore.Qt.Checked: if item1.text() == self.tr("Normal"): mode = QtGui.QIcon.Normal elif item1.text() == self.tr("Active"): mode = QtGui.QIcon.Active else: mode = QtGui.QIcon.Disabled if item2.text() == self.tr("On"): state = QtGui.QIcon.On else: state = QtGui.QIcon.Off fileName = item0.data(QtCore.Qt.UserRole).toString() image = QtGui.QImage(fileName) if not image.isNull(): icon.addPixmap(QtGui.QPixmap.fromImage(image), mode, state) self.previewArea.setIcon(icon) def addImage(self): fileNames = QtGui.QFileDialog.getOpenFileNames( self, self.tr("Open Images"), "", self.tr("Images (*.png *.xpm *.jpg);;All Files (*)")) if not fileNames.isEmpty(): for fileName in fileNames: row = self.imagesTable.rowCount() self.imagesTable.setRowCount(row + 1) imageName = QtCore.QFileInfo(fileName).baseName() item0 = QtGui.QTableWidgetItem(imageName) item0.setData(QtCore.Qt.UserRole, QtCore.QVariant(fileName)) item0.setFlags(item0.flags() & ~QtCore.Qt.ItemIsEditable) item1 = QtGui.QTableWidgetItem(self.tr("Normal")) item2 = QtGui.QTableWidgetItem(self.tr("Off")) if self.guessModeStateAct.isChecked(): if fileName.contains("_act"): item1.setText(self.tr("Active")) elif fileName.contains("_dis"): item1.setText(self.tr("Disabled")) if fileName.contains("_on"): item2.setText(self.tr("On")) self.imagesTable.setItem(row, 0, item0) self.imagesTable.setItem(row, 1, item1) self.imagesTable.setItem(row, 2, item2) self.imagesTable.openPersistentEditor(item1) self.imagesTable.openPersistentEditor(item2) item0.setCheckState(QtCore.Qt.Checked) def removeAllImages(self): self.imagesTable.setRowCount(0) self.changeIcon() def createPreviewGroupBox(self): self.previewGroupBox = QtGui.QGroupBox(self.tr("Preview")) self.previewArea = IconPreviewArea() layout = QtGui.QVBoxLayout() layout.addWidget(self.previewArea) self.previewGroupBox.setLayout(layout) def createImagesGroupBox(self): self.imagesGroupBox = QtGui.QGroupBox(self.tr("Images")) self.imagesGroupBox.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) labels = QtCore.QStringList() labels << self.tr("Image") << self.tr("Mode") << self.tr("State") self.imagesTable = QtGui.QTableWidget() self.imagesTable.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Ignored) self.imagesTable.setSelectionMode(QtGui.QAbstractItemView.NoSelection) self.imagesTable.setColumnCount(3) self.imagesTable.setHorizontalHeaderLabels(labels) self.imagesTable.setItemDelegate(ImageDelegate(self)) self.imagesTable.horizontalHeader().resizeSection(0, 160) self.imagesTable.horizontalHeader().resizeSection(1, 80) self.imagesTable.horizontalHeader().resizeSection(2, 80) self.imagesTable.verticalHeader().hide() self.connect(self.imagesTable, QtCore.SIGNAL("itemChanged(QTableWidgetItem *)"), self.changeIcon) layout = QtGui.QVBoxLayout() layout.addWidget(self.imagesTable) self.imagesGroupBox.setLayout(layout) def createIconSizeGroupBox(self): self.iconSizeGroupBox = QtGui.QGroupBox(self.tr("Icon Size")) self.smallRadioButton = QtGui.QRadioButton() self.largeRadioButton = QtGui.QRadioButton() self.toolBarRadioButton = QtGui.QRadioButton() self.listViewRadioButton = QtGui.QRadioButton() self.iconViewRadioButton = QtGui.QRadioButton() self.otherRadioButton = QtGui.QRadioButton(self.tr("Other:")) self.otherSpinBox = IconSizeSpinBox() self.otherSpinBox.setRange(8, 128) self.otherSpinBox.setValue(64) self.connect(self.toolBarRadioButton, QtCore.SIGNAL("toggled(bool)"), self.changeSize) self.connect(self.listViewRadioButton, QtCore.SIGNAL("toggled(bool)"), self.changeSize) self.connect(self.iconViewRadioButton, QtCore.SIGNAL("toggled(bool)"), self.changeSize) self.connect(self.smallRadioButton, QtCore.SIGNAL("toggled(bool)"), self.changeSize) self.connect(self.largeRadioButton, QtCore.SIGNAL("toggled(bool)"), self.changeSize) self.connect(self.otherRadioButton, QtCore.SIGNAL("toggled(bool)"), self.changeSize) self.connect(self.otherSpinBox, QtCore.SIGNAL("valueChanged(int)"), self.changeSize) otherSizeLayout = QtGui.QHBoxLayout() otherSizeLayout.addWidget(self.otherRadioButton) otherSizeLayout.addWidget(self.otherSpinBox) layout = QtGui.QGridLayout() layout.addWidget(self.smallRadioButton, 0, 0) layout.addWidget(self.largeRadioButton, 1, 0) layout.addWidget(self.toolBarRadioButton, 2, 0) layout.addWidget(self.listViewRadioButton, 0, 1) layout.addWidget(self.iconViewRadioButton, 1, 1) layout.addLayout(otherSizeLayout, 2, 1) self.iconSizeGroupBox.setLayout(layout) def createActions(self): self.addImageAct = QtGui.QAction(self.tr("&Add Image..."), self) self.addImageAct.setShortcut(self.tr("Ctrl+A")) self.connect(self.addImageAct, QtCore.SIGNAL("triggered()"), self.addImage) self.removeAllImagesAct = QtGui.QAction(self.tr("&Remove All Images"), self) self.removeAllImagesAct.setShortcut(self.tr("Ctrl+R")) self.connect(self.removeAllImagesAct, QtCore.SIGNAL("triggered()"), self.removeAllImages) self.exitAct = QtGui.QAction(self.tr("&Quit"), self) self.exitAct.setShortcut(self.tr("Ctrl+Q")) self.connect(self.exitAct, QtCore.SIGNAL("triggered()"), self, QtCore.SLOT("close()")) self.styleActionGroup = QtGui.QActionGroup(self) for styleName in QtGui.QStyleFactory.keys(): action = QtGui.QAction(self.styleActionGroup) action.setText(self.tr("%1 Style").arg(styleName)) action.setData(QtCore.QVariant(styleName)) action.setCheckable(True) self.connect(action, QtCore.SIGNAL("triggered(bool)"), self.changeStyle) self.guessModeStateAct = QtGui.QAction(self.tr("&Guess Image Mode/State"), self) self.guessModeStateAct.setCheckable(True) self.guessModeStateAct.setChecked(True) self.aboutAct = QtGui.QAction(self.tr("&About"), self) self.connect(self.aboutAct, QtCore.SIGNAL("triggered()"), self.about) self.aboutQtAct = QtGui.QAction(self.tr("About &Qt"), self) self.connect(self.aboutQtAct, QtCore.SIGNAL("triggered()"), QtGui.qApp, QtCore.SLOT("aboutQt()")) def createMenus(self): self.fileMenu = self.menuBar().addMenu(self.tr("&File")) self.fileMenu.addAction(self.addImageAct) self.fileMenu.addAction(self.removeAllImagesAct) self.fileMenu.addSeparator() self.fileMenu.addAction(self.exitAct) self.viewMenu = self.menuBar().addMenu(self.tr("&View")) for action in self.styleActionGroup.actions(): self.viewMenu.addAction(action) self.viewMenu.addSeparator() self.viewMenu.addAction(self.guessModeStateAct) self.menuBar().addSeparator() self.helpMenu = self.menuBar().addMenu(self.tr("&Help")) self.helpMenu.addAction(self.aboutAct) self.helpMenu.addAction(self.aboutQtAct) def createContextMenu(self): self.imagesTable.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) self.imagesTable.addAction(self.addImageAct) self.imagesTable.addAction(self.removeAllImagesAct) def checkCurrentStyle(self): for action in self.styleActionGroup.actions(): styleName = action.data().toString() candidate = QtGui.QStyleFactory.create(styleName) if candidate.metaObject().className() == QtGui.QApplication.style().metaObject().className(): action.trigger() return if __name__ == "__main__": app = QtGui.QApplication(sys.argv) mainWin = MainWindow() mainWin.show() sys.exit(app.exec_())