Using PyQT with QT Designer
Phil Thompson
phil at riverbankcomputing.com
Thu Aug 22 04:26:17 EDT 2013
On Wed, 21 Aug 2013 21:04:47 -0500, Michael Staggs <tausciam at gmail.com>
wrote:
> I'm learning Python and I have a problem. I've asked the question
> everywhere
> and no one helps me, so I'm hoping someone here will. I am making a
> program
> that shows album covers and you click on the album cover in the top
> window. In
> the bottom window, the list of songs appear and you can click the
> individual
> song to play it. It's going to be a media player for children. I'm
> thinking
> I'll be able to use a dict and have the album as the key and the list of
> songs
> as the value to accomplish this.
>
> Right now, I'm just using my picture directory to try and get the basic
> layout
> right. I designed a form in QT Designer: http://i.imgur.com/Wrp1zHW.png
>
> Here is my gui file I got from running pyuic4 on the ui file:
>
>
> # -*- coding: utf-8 -*-
>
> # Form implementation generated from reading ui file 'window.ui'
> #
> # Created by: PyQt4 UI code generator 4.9.6
> #
> # WARNING! All changes made in this file will be lost!
>
> from PyQt4 import QtCore, QtGui
>
> try:
> _fromUtf8 = QtCore.QString.fromUtf8
> except AttributeError:
> def _fromUtf8(s):
> return s
>
> try:
> _encoding = QtGui.QApplication.UnicodeUTF8
> def _translate(context, text, disambig):
> return QtGui.QApplication.translate(context, text, disambig,
> _encoding)
> except AttributeError:
> def _translate(context, text, disambig):
> return QtGui.QApplication.translate(context, text, disambig)
>
> class Ui_MainWindow(object):
> def setupUi(self, MainWindow):
> MainWindow.setObjectName(_fromUtf8("MainWindow"))
> MainWindow.resize(800, 600)
> self.centralwidget = QtGui.QWidget(MainWindow)
> self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
> self.tableWidget = QtGui.QTableWidget(self.centralwidget)
> self.tableWidget.setGeometry(QtCore.QRect(70, 20, 661, 381))
> self.tableWidget.setObjectName(_fromUtf8("tableWidget"))
> self.tableWidget.setColumnCount(0)
> self.tableWidget.setRowCount(0)
> self.listWidget = QtGui.QListWidget(self.centralwidget)
> self.listWidget.setGeometry(QtCore.QRect(70, 400, 661, 181))
> self.listWidget.setObjectName(_fromUtf8("listWidget"))
> MainWindow.setCentralWidget(self.centralwidget)
>
> self.retranslateUi(MainWindow)
> QtCore.QMetaObject.connectSlotsByName(MainWindow)
>
> def retranslateUi(self, MainWindow):
> MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow",
> None))
>
> Now, according to websites I read, I should just have to add the
following
> to
> my program to get it to use the form:
>
> from window import Ui_MainWindow
> class MainWindow(QMainWindow, Ui_MainWindow):
> def __init__(self, parent=None, **kwargs):
> super(MainWindow, self).__init__(parent)
> self.setupUi(self)
>
> and here is my program:
>
> from PyQt4.QtCore import *
> from PyQt4.QtGui import *
> from window import Ui_MainWindow
>
> THUMBNAIL_SIZE = 128
> SPACING = 10
> IMAGES_PER_ROW = 5
>
> class TableWidget(QTableWidget):
> def __init__(self, parent=None, **kwargs):
> QTableWidget.__init__(self, parent, **kwargs)
>
> self.setIconSize(QSize(128,128))
> self.setColumnCount(IMAGES_PER_ROW)
> self.setGridStyle(Qt.NoPen)
>
> # Set the default column width and hide the header
>
self.verticalHeader().setDefaultSectionSize(THUMBNAIL_SIZE+SPACING)
> self.verticalHeader().hide()
>
> # Set the default row height and hide the header
>
self.horizontalHeader().setDefaultSectionSize(THUMBNAIL_SIZE+SPACING)
> self.horizontalHeader().hide()
>
> # Set the table width to show all images without horizontal
> scrolling
>
self.setMinimumWidth((THUMBNAIL_SIZE+SPACING)*IMAGES_PER_ROW+(SPACING*2))
>
> def addPicture(self, row, col, picturePath):
> item=QTableWidgetItem()
>
> # Scale the image by either height or width and then 'crop' it
to
> the
> # desired size, this prevents distortion of the image.
> p=QPixmap(picturePath)
> if p.height()>p.width(): p=p.scaledToWidth(THUMBNAIL_SIZE)
> else: p=p.scaledToHeight(THUMBNAIL_SIZE)
> p=p.copy(0,0,THUMBNAIL_SIZE,THUMBNAIL_SIZE)
> item.setIcon(QIcon(p))
>
> self.setItem(row,col,item)
>
> class MainWindow(QMainWindow, Ui_MainWindow):
> def __init__(self, parent=None, **kwargs):
> super(MainWindow, self).__init__(parent)
> self.setupUi(self)
>
> centralWidget=QWidget(self)
> l=QVBoxLayout(centralWidget)
>
> self.tableWidget=TableWidget(self)
> l.addWidget(self.tableWidget)
>
> self.setCentralWidget(centralWidget)
>
>
picturesPath=QDesktopServices.storageLocation(QDesktopServices.PicturesLocation)
> pictureDir=QDir(picturesPath)
> pictures=pictureDir.entryList(['*.jpg','*.png','*.gif'])
>
> rowCount=len(pictures)//IMAGES_PER_ROW
> if len(pictures)%IMAGES_PER_ROW: rowCount+=1
> self.tableWidget.setRowCount(rowCount)
>
> row=-1
> for i,picture in enumerate(pictures):
> col=i%IMAGES_PER_ROW
> if not col: row+=1
> self.tableWidget.addPicture(row, col,
> pictureDir.absoluteFilePath(picture))
>
> if __name__=="__main__":
> from sys import argv, exit
>
> a=QApplication(argv)
> m=MainWindow()
> m.show()
> m.raise_()
> exit(a.exec_())
>
> But, it doesn't work. It ignores the form and the two windows go from
side
> to
> side in the frame. When I add buttons, it adds them on TOP of those two
> windows instead of beside them in the empty space....because there is no
> empty
> space.
>
> http://i.imgur.com/ZQfsMDa.png
>
> Please tell me what I'm doing wrong.
It looks like you aren't using a layout to arrange your widgets.
Explicitly specifying geometries is a bad idea.
Phil
More information about the Python-list
mailing list