prog_linenum

2024年3月17日 星期日

【PySide6】視窗事件_視窗本身相關事件

 本文主要是了解視窗事件被觸發的相關時機。


先給一段程式碼:

"""
程式名稱:form_event.py
程式功能:
1. 視窗事件被觸發的相關時機
"""
import sys
from PySide6.QtGui import QFocusEvent
from PySide6.QtWidgets import (
    QWidget, QApplication)

class MyApp(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('form_event.py')
        self.setGeometry(400, 250, 500, 300)
        self.show()

    def changeEvent(self, event):
        print('changeEvent')
        
    def closeEvent(self, event):
        print('closeEvent')

    def hideEvent(self, event):
        print('hideEvent')
        
    def moveEvent(self, event):
        print('moveEvent')
        
    def resizeEvent(self, event):
        print('resizeEvent')
        
    def showEvent(self, event):
        print('showEvent')

if __name__ == '__main__':
    app = QApplication()
    my_app = MyApp()
    sys.exit(app.exec())


底下為console輸出訊息:
視窗啟動時:
changeEvent
moveEvent
resizeEvent
showEvent
paintEvent
paintEvent
changeEvent
paintEvent

視窗縮小至工作列時:
changeEvent
hideEvent
changeEvent

視窗被其它視窗蓋住/當其它視窗移開:
(此視窗要為作用中視窗,如果用滑鼠移動其它視窗去遮蓋、移開,因動作視窗是在滑鼠所按住的視窗,故不會觸發事件)
changeEvent
paintEvent

視窗重新顯示時:
showEvent
changeEvent
changeEvent
paintEvent

視窗移動時:
一直觸發moveEvent

視窗調整大小時:
changeEvent
paintEvent
resizeEvent
paintEvent   .... 
resizeEvent  ....

當視窗關閉時:
changeEvent
closeEvent
changeEvent
hideEvent

事件被觸發的時機
函式名稱 何時觸發
changeEvent
  • 視窗啟動
  • 視窗縮小至工作列
  • 視窗被其它視窗蓋住/當其它視窗移開
  • 視窗重新顯示
  • 視窗調整大小時
  • 視窗關閉時
closeEvent
  • 視窗關閉
hideEvent
  • 視窗縮小至工作列
  • 視窗關閉
moveEvent
  • 視窗啟動
  • 視窗移動
paintEvent
  • 視窗啟動
  • 視窗被其它視窗蓋住/當其它視窗移開
  • 視窗重新顯示
  • 視窗調整大小
resizeEvent
  • 視窗啟動
  • 視窗被其它視窗蓋住/當其它視窗移開
  • 視窗調整大小
showEvent
  • 視窗啟動
  • 視窗重新顯示

有時一個操作動作當中,事件不只被觸發一次,如changeEvent在很多操作當中就被觸發多次。有些是連續觸發,如滑鼠移動視窗就會一直觸發moveEvent。

2024年3月14日 星期四

【Python】if __name__ == '__main__': 判斷式解析


在python程式碼有時會看到if __name__ == '__main__': 的判斷式,其用途是判斷目前所執行的python檔案是以主程式或以模組的方式執行。


先建立一名為mod1.py的檔案

def module_name_show():
    print('mod1.py 的__name__名稱為:', __name__)

if __name__ == '__main__':
    print('mod1.py 以主程式方式執行')
    module_name_show()
else:
    print('mod1.py 以模組方式執行')

程式執行結果:






說明:

1. 當直接執行程式時,列印出"mod1.py 以主程式方式執行",故得知其__name__的名稱為__main__才會執行if條件成立的敘述。

2. 然後再呼叫函式module_name_show()列印__name__名稱。


接下來再建立一名為mod1_main.py的檔案。

import mod1

if __name__ == '__main__':
    print('mod1_main.py的__name__名稱為:',__name__)
    mod1.module_name_show()

執行該mod1_main.py程式,結果如下:





由執行結果可得知:

1. import模組時,會先執行模組內的if判斷敘述。而所列印的結果得知,是else區段,故可知其__name__名稱不是__main__。

2. 當import完後,才會執行主程式的if判斷敘述。列印出所執行程式的__name__名稱。列印出來為__main__。

3. 接下來再呼叫mod1模組內的module_name_show()函式。而此時其函式所列印的__name1__名稱為mod1,也就是模組(檔名)名稱。



結論,由以上程式的示範可得知:

1. 當直接執行該檔案時,其__name__名稱為:__main__。

2. 當該檔案被另一個檔案當模組import時,其__name__名稱為該模組(檔名)名稱。




2024年3月13日 星期三

【網頁編輯】程式碼行號顯示,使用code-prettify

由於要在Blogger貼上程式碼的緣故,關於顯示行號,google搜尋了很多內容。加上自己本身不是摸前端的,只是想找個簡便的方法來顯示程式碼行號。


在此使用code-prettify

code-prettify網址


STEP1:

進入版面配置,點選「+新增小工具」









STEP2:

選擇「HTML JavaScript工具」













STEP3:

3-1. 標題隨意命名一個名稱,如:prog_linenum

3-2.貼上code-prettify的cdn網址:

<script src="https://cdn.jsdelivr.net/gh/google/
code-prettify@master/loader/run_prettify.js"></script>



完畢後按「儲存」


STEP4:


最後記得按下右下方的儲存,以儲存版面。











至此,第一階段設定完畢。

接下來就可以新增文章,切換到「HTML檢視」,插入下列html碼:

<pre class="prettyprint linenums">
...程式碼...
</pre>


示範程式碼,圖片1,程式碼超出範圍會溢出。

示範程式碼,圖片2,程式碼一列到底,也沒有卷軸。

注意:

程式碼用<pre></pre>包起來就好,有些網站上還有在<pre>內包上<code>,但測試結果會發覺行數會計算錯誤,以及灰、白相隔的背景顯示也會錯亂。

如下圖所示:














接下來就是要進行第二階段設定,主要是解決文字超出版面、沒有卷軸問題

STEP1:

進入主題設定,找一些資料,都會建議版面使用Simple樣式,在此,也是用網站建議的方式。














STEP2:

按下自訂旁的下拉箭頭,選擇編輯HTML


















找尋<style type='text/css'>的地方。由於有快千行的程式碼,且使用網頁的搜尋是找不到的。我的方式是把它貼到文字編輯器,如Notepad++,然後搜尋text/css,利用Notepad++顯示的行數對應到Blogger HTML編輯器的行數。









所找出的位置處








插入下列CSS程式碼:

pre.prettyprint{
width: auto;
overflow: auto;
max-height: 600px}

由於<style>本身有些程式碼已存在,所以新增的CSS程式碼把它插在</style>前方。如下圖所示:














程式碼貼完後,記得按 HTML編輯器右上方的儲存鈕。






最後,程式碼畫面行號正常顯示、且有卷軸。


















預設行號顯示為每隔五行,如果要每行顯示,則必須在剛設定的style中,再添加程式碼。

li.L0, li.L1, li.L2, li.L3,li.L5, li.L6, li.L7, li.L8 {   
list-style-type: decimal;}









結果如下:




2024年3月8日 星期五

test

測試...

"""
程式功能:
1. 基本視窗建立
2. 如何計算視窗在螢幕中間位置
3. 如何計算label元件在視窗中位置
4. 如何在調整視窗大小時,label元件固定在視窗中央
5. 如何取得滑鼠移動座標

"""
import sys
from PySide6.QtCore import Qt
from PySide6.QtGui import QFont
from PySide6.QtWidgets import (
    QWidget, QLabel, QApplication)


class MyApp(QWidget):
    def __init__(self):
        # super(MyApp, self).__init__()
        # super()參數列可省略
        super().__init__()
        self.param_init()
        # 建立Label
        self.lblTextShow = QLabel(self)
        self.lblMousePos = QLabel(self)
        # 初始化界面
        self.init_ui()

    def param_init(self):
        """
        全域參數初始化
        :return: None
        """

        self.MAIN_WINDOW_SIZE_WIDTH: int = 300
        self.MAIN_WINDOW_SIZE_HEIGHT: int = 300
        self.LABEL_SIZE_WIDTH: int = 100
        self.LABEL_SIZE_HEIGHT: int = 50
        self.LABEL_SIZE_WIDTH_HALF: int = self.LABEL_SIZE_WIDTH // 2
        self.LABEL_SIZE_HEIGHT_HALF: int = self.LABEL_SIZE_HEIGHT // 2

        self.SCREEN_CENTER_WIDTH = self.screen().size().width() // 2
        self.SCREEN_CENTER_HEIGHT = self.screen().size().height() // 2

    def init_ui(self):
        self.set_main_window_center()
        self.setWindowTitle('基本視窗示範')  # 設定視窗抬頭
        self.setMouseTracking(True)  # 要為True才能觸發mouseMoveEvent()事件
        self.lblTextShow.setGeometry(100, 100,
                                     self.LABEL_SIZE_WIDTH,
                                     self.LABEL_SIZE_HEIGHT)

        self.lblTextShow.setText("Hello World!")
        self.lblMousePos.setText("(0,0)")
        self.lblMousePos.setFont(QFont('Arial', 18))
        self.lblMousePos.resize(150, self.lblMousePos.height())
        self.lblMousePos.move(10, 10)

        self.lblTextShow.setStyleSheet("background-color: gold")
        self.lblMousePos.setStyleSheet("background-color:lightgreen")

        self.lblTextShow.setAlignment(Qt.AlignmentFlag.AlignHCenter.AlignCenter)

        self.show()

    def set_main_window_center(self) :
        """
        設定視窗在螢幕正中央
        :return:
        """
        # 取得視窗中間位置
        mw_x_pos = self.SCREEN_CENTER_WIDTH - (self.MAIN_WINDOW_SIZE_WIDTH // 2)
        mw_y_pos = self.SCREEN_CENTER_HEIGHT - (self.MAIN_WINDOW_SIZE_HEIGHT // 2)
        # 設定視窗位置、大小(x,y,w,h)
        self.setGeometry(mw_x_pos, mw_y_pos,
                         self.MAIN_WINDOW_SIZE_WIDTH,
                         self.MAIN_WINDOW_SIZE_HEIGHT)

    # 視窗當建立時、有變更大小時會觸發
    def resizeEvent(self, event):
        print('resize')
        w = (self.width() // 2) - self.LABEL_SIZE_WIDTH_HALF
        h = (self.height() // 2) - self.LABEL_SIZE_HEIGHT_HALF

        self.lblTextShow.setGeometry(w, h,
                                     self.LABEL_SIZE_WIDTH,
                                     self.LABEL_SIZE_HEIGHT)

    def mouseMoveEvent(self, event):
        # self.label.setText('Mouse coords: ( %d : %d )' % (event.x(), event.y()))
        self.lblMousePos.setText('( %d : %d )' % (event.x(), event.y()))
        print('Mouse coords: ( %d : %d )' % (event.x(), event.y()))


if __name__ == '__main__':
    app = QApplication()
    ex = MyApp()
    sys.exit(app.exec())

2024年2月21日 星期三

【設計工具】如何變更QT Designer介面語言

起因:

        QT Designer會因所安裝的系統,而顯示不同的語言。如在win11繁中系統下,介面顯示為繁中。在樹梅派英文的Linux系統下,介面顯示為英文。但軟體中並沒有更改介面語言的選項。












處理步驟:

1. 進到PySide6的translations資料夾內。

2. 把designer_zh_TW.qm改一下名字,如_designer_zh_TW.qm

3. 重新開啟QT Designer,因為找不到翻譯檔,所以軟體預設為英文。
















更改後的介面選單顯示:










【PySide6】視窗事件_視窗本身相關事件

 本文主要是了解視窗事件被觸發的相關時機。 先給一段程式碼: """ 程式名稱:form_event.py 程式功能: 1. 視窗事件被觸發的相關時機 """ import sys from PySide6.QtGu...