Skip to content

[PyQt5] 基本教學(3) QMainWindow, QIcon, QPixmap, QPalette

Last Updated on 2021-04-08 by Clay

今天趁著跑實驗的空檔嘗試一下如何在 PyQt5 中拉出棋盤,在這過程中嘗試了許多不同的窗口功能,故今天就把其整理成筆記,這樣也方便以後翻看 XDD

今天應該分成四個部份:設定窗口標題、設定 Icon、設定背景、隱藏欄位 ....... 總覺得最後一項幾乎打掉了前面所有的努力啊 XDD

廢話不多說,我們就開始吧!


設定窗口標題

首先,這應該是我們打開 Qt Designer 時的長相。

如果我們不做任何動作、不新增任何元件,直接儲存這個 UI 檔,然後將其轉成 Python 檔。

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'QMainWindow.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(873, 705)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 873, 25))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))


可以看到,這次自動生成的界面檔非常單純,基本上只定義了 MainWindow、Menubar、Statusbar ..... 之類基本的元件。

我們再次開啟新的 Python 檔,實做邏輯、界面分離的動作。

# -*- coding: utf-8 -*-
from PyQt5 import QtWidgets, QtGui
from QMainWindow import Ui_MainWindow
import sys


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)


if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())


Output:

我們可以看到什麼東西都沒有的原始視窗!

其中,若想設定上方的程式名稱、我們可以用一個簡單的程式修改。

# -*- coding: utf-8 -*-
from PyQt5 import QtWidgets, QtGui
from QMainWindow import Ui_MainWindow
import sys


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # MainWindow Title
        self.setWindowTitle('QIcon Test!!')


if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())


Output:

標題名稱改了!

因為我們定義的新 class 就是按照繼承了原先的 MainWindow 這個類別,故我們只需要調用自己 setWindowTitle() 就可以任意地修改我們想要的標題。

其實,我們也可以任意定義下方的狀態欄 StatusBar。

# -*- coding: utf-8 -*-
from PyQt5 import QtWidgets, QtGui
from QMainWindow import Ui_MainWindow
import sys


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # MainWindow Title
        self.setWindowTitle('QIcon Test!!')

        # StatusBar
        self.statusBar().showMessage('TEST Again!!!')


if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())


Output:

左下角也出現了我們設定的文字。

如何,是不是很輕易就可以設定呢?


設定 Icon

緊接著,我們來設定窗口圖示。

基本上我們只需要一行指令:

self.setWindowIcon(QtGui.QIcon('pic/Python_PyQt5.png'))
# -*- coding: utf-8 -*-
from PyQt5 import QtWidgets, QtGui
from QMainWindow import Ui_MainWindow
import sys


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # MainWindow Title
        self.setWindowTitle('QIcon Test!!')

        # StatusBar
        self.statusBar().showMessage('TEST Again!!!')

        # Set Window Icon
        self.setWindowIcon(QtGui.QIcon('pic/Python_PyQt5.png'))


if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())


Output:

我們可以對比一下以上的圖,是不是發現 Icon (左上角)換了圖示了呢?
當然,我覺得有點不起眼,有點不好意思哈哈哈哈。

原圖長這樣:

其實就是我開頭放的那個圖片!如有侵權請告知,我會馬上刪掉的!


設定背景

那麼接下來,就來到我折騰很久的背景吧!其實背景意外地好設定,不過我們需要介紹兩個新的元件: QPalette、QPixmap

顧名思義,QPixmap 就是像素圖,我們可以把圖片讀取進來;而 QPalette 就是調色盤,我們可以在上面任意放置顏色。在這裡的教學便是將 QPixmap 讀取進來的圖片傳給 QPalette,然後再將 QPalette 這個物件傳遞給我們的 MainWindow。

# -*- coding: utf-8 -*-
from PyQt5 import QtWidgets, QtGui
from QMainWindow import Ui_MainWindow
import sys


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # MainWindow Title
        self.setWindowTitle('QIcon Test!!')

        # StatusBar
        self.statusBar().showMessage('TEST Again!!!')

        # Set Window Icon
        self.setWindowIcon(QtGui.QIcon('pic/Python_PyQt5.png'))

        # Pixmap
        image = QtGui.QPixmap()
        image.load('pic/Python_PyQt5.png')
        image = image.scaled(self.width(), self.height())

        # Palette
        palette = QtGui.QPalette()
        palette.setBrush(self.backgroundRole(), QtGui.QBrush(image))
        self.setPalette(palette)


if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())


Output:

其中:

image.scaled(self.width(), self.height())

這行指令我做了圖片的大小調整,避免圖片大到視窗放不下,當然你會看到,可能圖片有些變形。

順帶一題,如果我們背景不打算放置圖片,而是打算上背景顏色的話:

# -*- coding: utf-8 -*-
from PyQt5 import QtWidgets, QtGui
from QMainWindow import Ui_MainWindow
import sys


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # MainWindow Title
        self.setWindowTitle('QIcon Test!!')

        # StatusBar
        self.statusBar().showMessage('TEST Again!!!')

        # Set Window Icon
        self.setWindowIcon(QtGui.QIcon('pic/Python_PyQt5.png'))

        # Pixmap
        # image = QtGui.QPixmap()
        # image.load('pic/Python_PyQt5.png')
        # image = image.scaled(self.width(), self.height())
        #
        # Palette
        palette = QtGui.QPalette()
        palette.setBrush(self.backgroundRole(), QtGui.QColor(150, 200, 100))
        self.setPalette(palette)


if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())


Output:

就像這樣!

我們把 palette.setBrush() 裡的傳給的物件改成 QtGui.QColor(),然後裡面填著 RGB 三原色,就可以直接替背景上色。


隱藏窗口上方欄位

沒錯,終於來到我們浪費上頭努力的部份啦!

我們其實只需要使用一個指令,便可以輕鬆隱藏我們的 Window Title:

# -*- coding: utf-8 -*-
from PyQt5 import QtWidgets, QtGui, QtCore
from QMainWindow import Ui_MainWindow
import sys


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # MainWindow Title
        self.setWindowTitle('QIcon Test!!')

        # StatusBar
        self.statusBar().showMessage('TEST Again!!!')

        # Set Window Icon
        self.setWindowIcon(QtGui.QIcon('pic/Python_PyQt5.png'))

        # Pixmap
        image = QtGui.QPixmap()
        image.load('pic/Python_PyQt5.png')
        image = image.scaled(self.width(), self.height())

        # Palette
        palette = QtGui.QPalette()
        palette.setBrush(self.backgroundRole(), QtGui.QBrush(image))
        self.setPalette(palette)

        # Hide Window Title
        self.setWindowFlag(QtCore.Qt.FramelessWindowHint)


if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())


Output:

如何?是不是真的去掉了煩人的框框呢?要是我們再針對邊角做優化,一個充滿時尚感的界面就做出來啦!

也許在我的記譜程式完成之後會想針對界面再做優化,到時候再紀錄心得筆記吧!


References


Read More

Leave a Reply