PySide——Python圖形化界面入門教程(五)


PySide——Python圖形化界面入門教程(五)

              ——QListWidget

翻譯自:http://pythoncentral.io/pyside-pyqt-tutorial-the-qlistwidget/

Qt具有簡潔和方便的幾個部件,用來作單列表選擇,我們稱之為列表框。最靈活的方法是使用一個是Qlistview,它提供了一個必須由程序員定義UI視圖、高度靈活的列表模式;一個簡單的方法是使用QListWidget,它具有一個預先定義的基於項目的模型,用來處理常見的列表框。我們本節從簡單的QListWidget開始。

 

QListWidget

QListWidget的構造器同許多QWidget的子類一樣,擁有一個可選的parent參數:

self.list = QListWidget(self)

 

填充QListWidget

為QListWidget添加項目非常容易。如果項目是純文本,你可以單獨的添加他們:

1 for i in range(10):
2     self.list.addItem('Item %s' % (i + 1))

或者一起添加他們:

1 items = ['Item %s' % (i + 1)
2          for i in range(10)]
3 self.list.addItems(items)

你還可以使用QListWidgetItem類更復雜的列表項目。QListWidgetItem可以被單獨的創建,然后再使用列表的addItem方法添加。

item = QListWidgetItem()
list.addItem(item)

 

更復雜的QListWidget項目

或者,它還可以直接使用list參數來創建,這樣他會自動的被添加到list。

item = QListWidgetItem(list)

項目可以使用setText方法來添加文本,使用setIcon方法添加圖標QIcon:

item.setText('I am an item')
item.setIcon(some_QIcon)

同樣也可以在構造器中寫明文本或圖標:

item = QListWidgetItem('A Text-Only Item')
item = QListWidgetItem(some_QIcon, 'An item with text and an icon')

當然, 上面的每個構造器也可選的接受parent參數。

 

使用QListWidget

QListWidget提供一些方便的信號來響應用戶輸入。最重要的是currentItemChanged信號,它是當用戶改變選擇的項目時發出;它連接的槽接收兩個參數,current和previous,表示現在和之前選擇的QListWidgetItem項。同樣它也有對應的信號,當用戶單擊、雙擊、激活或按下一個項、改變選擇的項目集時。

為獲得當前選擇的項,你也可以使用currentItemChanged信號傳來的參數,或使用QListWidget的currentItem方法。

 

對QIcon的注解

你可以通過添加一個圖標來改變QListWidgetItem,所以有必要了解一下QIcon了。這有許多構造QIcon的方法,如:

  • 提供文件名: icon = QIcon('/some/path/to/icon.png').
  • 使用主題圖標: icon = QIcon.fromTheme('document-open').
  • 通過QPixMap: icon = QIcon(some_pixmap)

還有許多其他的。注意:基於文件的創建方法支持許多類型,但並不是所有類型,你可以通過使用QImageReader().supportedImageFormats()來查看你的平台和版本支持哪些。在作者的系統上,它返回了:

 1 [PySide.QtCore.QByteArray('bmp'),
 2  PySide.QtCore.QByteArray('gif'),
 3  PySide.QtCore.QByteArray('ico'),
 4  PySide.QtCore.QByteArray('jpeg'),
 5  PySide.QtCore.QByteArray('jpg'),
 6  PySide.QtCore.QByteArray('mng'),
 7  PySide.QtCore.QByteArray('pbm'),
 8  PySide.QtCore.QByteArray('pgm'),
 9  PySide.QtCore.QByteArray('png'),
10  PySide.QtCore.QByteArray('ppm'),
11  PySide.QtCore.QByteArray('svg'),
12  PySide.QtCore.QByteArray('svgz'),
13  PySide.QtCore.QByteArray('tga'),
14  PySide.QtCore.QByteArray('tif'),
15  PySide.QtCore.QByteArray('tiff'),
16  PySide.QtCore.QByteArray('xbm'),
View Code

基於主題的創建方法有時候會出問題,當在Windows和OS X還有使用Gnome或KDE的Linux應該沒問題,但是如果使用不太常見的桌面環境,像OpenBox或XFCE,Qt或許不能找到你的圖標,所以會只有文本。

 

一個QListWidget例子

我們來創建一個簡單的列表widget來顯示文件夾中的文件名和為圖片顯示一個極小的圖標。因為這里的項非常簡單,足以用QListWidgetItem來創建,我們將從QListWidget繼承。

第一步,我們需要知道安裝的版本都支持什么類型的圖片,這樣我們的列表控件才能辨別什么是合法的圖片。我們可以使用上面提到的方法,QImageReader().supportedImageFormats()。我們將他們返回前全部轉化成字符串:

1 def supported_image_extensions():
2     ''' Get the image file extensions that can be read. '''
3     formats = QImageReader().supportedImageFormats()
4     # Convert the QByteArrays to strings
5     return [str(fmt) for fmt in formats]

現在我們可以創建我們的圖片列表widget了,起一個望名知義的名字——ImageFileWidget。它將繼承自QListWidget,還像所有的QWidget一樣有一個可選的parent參數,此外,它要求一個dirpath參數:

1 class ImageFileList(QListWidget):
2     ''' A specialized QListWidget that displays the list
3         of all image files in a given directory. '''
4     def __init__(self, dirpath, parent=None):
5         QListWidget.__init__(self, parent)

我們需要知道給出的文件夾中都有哪些圖片。這里給出一個_images方法,這個方法會返回指定目錄中所有合法圖片的文件名。它利用了glob模塊的glob函數,它允許對文件和路徑進行shell風格的模式匹配。

 1 def _images(self):
 2     ''' Return a list of file-names of all
 3         supported images in self._dirpath. '''
 4  
 5     # Start with an empty list
 6     images = []
 7  
 8     # Find the matching files for each valid
 9     # extension and add them to the images list.
10     for extension in supported_image_extensions():
11         pattern = os.path.join(self._dirpath,
12                                '*.%s' % extension)
13         images.extend(glob(pattern))
14  
15     return images
View Code

現在我們獲得了文件夾中的圖片文件,再將他們添加到QListWidget就簡單了。每一個文件名,我們創建一個以列表為其parent的QListWidgetItem,並將其文件名設置成本文,用圖片創建的QIcon設置其圖標。

 1 def _populate(self):
 2     ''' Fill the list with images from the
 3         current directory in self._dirpath. '''
 4  
 5     # In case we're repopulating, clear the list
 6     self.clear()
 7  
 8     # Create a list item for each image file,
 9     # setting the text and icon appropriately
10     for image in self._images():
11         item = QListWidgetItem(self)
12         item.setText(image)
13         item.setIcon(QIcon(image))
View Code

最后,我們添加一個方法來設置目錄,它每次調用都會重新填充列表。

1 def setDirpath(self, dirpath):
2     ''' Set the current image directory and refresh the list. '''
3     self._dirpath = dirpath
4     self._populate()

ImageFileList類的代碼如下:

 1 class ImageFileList(QListWidget):
 2     ''' A specialized QListWidget that displays the
 3         list of all image files in a given directory. '''
 4  
 5     def __init__(self, dirpath, parent=None):
 6         QListWidget.__init__(self, parent)
 7         self.setDirpath(dirpath)
 8  
 9  
10     def setDirpath(self, dirpath):
11         ''' Set the current image directory and refresh the list. '''
12         self._dirpath = dirpath
13         self._populate()
14  
15  
16     def _images(self):
17         ''' Return a list of filenames of all
18             supported images in self._dirpath. '''
19  
20         # Start with an empty list
21         images = []
22  
23         # Find the matching files for each valid
24         # extension and add them to the images list
25         for extension in supported_image_extensions():
26             pattern = os.path.join(self._dirpath,
27                                    '*.%s' % extension)
28             images.extend(glob(pattern))
29  
30         return images
31  
32  
33     def _populate(self):
34         ''' Fill the list with images from the
35             current directory in self._dirpath. '''
36  
37         # In case we're repopulating, clear the list
38         self.clear()
39  
40         # Create a list item for each image file,
41         # setting the text and icon appropriately
42         for image in self._images():
43             item = QListWidgetItem(self)
44             item.setText(image)
45             item.setIcon(QIcon(image))
View Code

 

現在把我們的ImageFileList放到一個簡單窗口里來看看它是否工作。我們將創建一個QWidget來作為窗口,使用QVBoxLayout布局,添加ImageFileList,並且包含一個可以顯示當前選定項的記錄widget。我們將使用ImageFileList的currentItemChanged信號來保持他們同步。

我們將創建一個QApplication對象,使用sys.argv[1],以列表形式傳遞圖片文件路徑給它。

app = QApplication([])

然后,創建我們的窗口,設置尺寸並添加布局:

1 win = QWidget()
2 win.setWindowTitle('Image List')
3 win.setMinimumSize(600, 400)
4 layout = QVBoxLayout()
5 win.setLayout(layout)

接下來,傳遞給ImageFileList圖片文件夾路徑和我們的窗口。

first = ImageFileList(sys.argv[1], win)

添加記錄widget

entry = QLineEdit(win)

將widget添加到布局中去:

layout.addWidget(first)
layout.addWidget(entry)

接下來,我們需要創建一個在當前項被改變時會調用的槽函數。它有兩個參數,curr和prev,分別表示當前選定的項和上一個選定的項。它還需要設置記錄當前選定的項:

def on_item_changed(curr, prev):
    entry.setText(curr.text())

別忘了和信號連接起來:

lst.currentItemChanged.connect(on_item_changed)

剩下的就是顯示窗口和運行app了,最后代碼如下:

 1 if __name__ == '__main__':
 2     # The app doesn't receive sys.argv, because we're using
 3     # sys.argv[1] to receive the image directory
 4     app = QApplication([])
 5  
 6     # Create a window, set its size, and give it a layout
 7     win = QWidget()
 8     win.setWindowTitle('Image List')
 9     win.setMinimumSize(600, 400)
10     layout = QVBoxLayout()
11     win.setLayout(layout)
12  
13     # Create one of our ImageFileList objects using the image
14     # directory passed in from the command line
15     lst = ImageFileList(sys.argv[1], win)
16  
17     layout.addWidget(lst)
18  
19     entry = QLineEdit(win)
20  
21     layout.addWidget(entry)
22  
23     def on_item_changed(curr, prev):
24         entry.setText(curr.text())
25  
26     lst.currentItemChanged.connect(on_item_changed)
27  
28     win.show()
29     app.exec_()
View Code

運行這個例子需要你有一個具有圖片的文件夾;原文作者使用了/usr/share/icons作為例子,你需要選擇自己的文件夾。

python imagelist.py /usr/share/icons/nuoveXT2/48x48/devices

應有些朋友的要求,給出一個運行的截圖。另外需要注意自行import一些庫才可以運行。

顯然,QListWidget是非常簡單的widget,不需要提供更多的選項;這就會有許多它不能適應的應用場景。對於難以適應的場景,你或許需要使用QListView,我們在下節討論它。

 

By Ascii0x03

轉載請注明出處:http://www.cnblogs.com/ascii0x03/p/5502286.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM