django Tutorial 筆記
Python除了寫爬蟲、小工具方便又快速之外,其中最有名的,就是做為網頁後端使用的django了!跟著官方的tutorial試做一次,記錄自己容易忘記的地方
Python除了寫爬蟲、小工具方便又快速之外,其中最有名的,就是做為網頁後端使用的django了!跟著官方的tutorial試做一次,記錄自己容易忘記的地方
後端採用django,前端使用框架的架構。卻會遇到垮域無法互丟資料的問題…
在QTableWidget中,呈現TABLE的方式是從1開始
但實際儲存方式,則是從0開始
也就是要刪除看到的第一列,參數要給0
self.ui.tableWidget.removeRow(0) #刪除看到的第一列
self.ui.tableWidget.removeRow(1) #刪除看到的第二列
self.ui.tableWidget.removeRow(N-1) #刪除看到的第N列
但是要多選刪除時
就不是簡單的跑一個迴圈就行了
items = self.ui.tableWidget.selectedIndexes()
wannaDelRows = [item.row() for item in items]
for row in wannaDelRows:
self.ui.tableWidget.removeRow(row)
實際運行會發現,只有第一列正確被刪除,其他列似乎全都不對了?!
錯誤的原因是因為第一列被刪除後,該列後方的所有位置也跟著減-1了!
也就是當你只是單純地使用selectedIndexes()取得多選的列來刪除的話,從第2筆開始的指到row,已經不在是當初user選到要刪除的row了!
那該怎麼解決呢?
從後面開始刪除就行了!
為避免user選的item是同一個row不同column
造成同一個row取到2次,導致跑迴圈時刪除到不應該被刪掉的
因此還需要搭配set確保要刪除的row只會被執行一次
將原本的程式碼修改如下
items = self.ui.tableWidget.selectedIndexes()
wannaDelRows = [item.row() for item in items]
wannaDelRowsReverse = sorted(set(wannaDelRows),reverse=True)
for row in wannaDelRowsReverse:
self.ui.tableWidget.removeRow(row)
稍微查一下PyQt5的語法,就會知道搭配Signal就可以讓cell被更動時觸發,並執行你要做的事
下列片段以本次主題:自動轉大寫為例
def __init__(self):
#...省略其他片段
self.ui.tableWidget.itemChanged.connect(self.upperText)
#...省略其他片段
def upperText(self):
item = self.ui.tableWidget.currentItem()
item.setText(item.text().upper())
self.ui.tableWidget.setItem(item.row(),item.column(),item)
確實,這樣寫並沒有問題 ── 只限於你的TABLE預設就有塞值在裡面
實務上,user倒入資料後(或是一啟動就直接連接資料庫取值),會發現程式直接崩潰
為什麼呢?
因為QTableWidget每次setItem時,都會觸發一次itemChanged!
而目前的table是空的,裡面沒有任何item,導致item.setText()這裡,找不到setText這個函數,於是程式就死掉了
解決方法就是
倒入資料到table時,暫停signal
在你放入資料的函數裡,頭尾分加入關閉、啟動signal就行了!
def putIntoTable(self):
+ self.ui.tableWidget.blockSignals(True)
for i in range(10):
self.ui.tableWidget.insertRow(i)
self.ui.tableWidget.setItem(i,0,QTableWidgetItem(str(i)))
+ self.ui.tableWidget.blockSignals(False)
如果有許多地方需要暫停的話,可以把他寫成裝飾器(decorator),就不用再每個頭尾都加開關嘍
from functools import wraps # 使用裝飾器(decorator),記得要import
def _blockSignals(f):
@wraps(f)
def wrapper(self):
self.ui.tableWidget.blockSignals(True)
f(self)
self.ui.tableWidget.blockSignals(False)
return wrapper
@_blockSignals
def putIntoTable(self):
for i in range(10):
self.ui.tableWidget.insertRow(i)
self.ui.tableWidget.setItem(i,0,QTableWidgetItem(str(i)))
參考資料
明明在開發環境下執行都正常,打包後,卻都是預設的icon…
大部份的離線安裝方式,只要python setup.py就行,但pyinstaller卻不太一樣
使用pyinstaller打包exe檔,常用到的參數一覽
大部份的使用者選購的MacBook,多半落在256gb。畢竟再往上,那價錢更是高不可攀。原本的空間就不太夠用,偶爾又還是得用上Windows,有辦法裝在隨身碟上嗎??
明明帳號就有管理員權限,跳出這個訊息時真的是頗傻眼。
Google都找不太到解法,轉成簡體字後才找到…
一開始找到的解法也很妙,是新建一個非管理員權限來啟動BOOTCAMP控制台,就可以正常。這…根本不會想到要繞這種彎路啊!而且這樣操作也太痛苦!所幸最後有大神提供完美解決方法
C:\Windows\System32\AppleControlPanel.exe
,把檔案複製到桌面Resource Hacker
打開複製出來的AppleControlPanel.exe
24/1/1033
的路徑下,對1033右鍵>刪除資源
檔案>另存新檔>AppleControlPanel2.exe
**AppleControlPanel2.exe
就可以用了,但為了以後方便在常駐列可以直接執行,繼續後面步驟工作管理員
,將BOOTCAMP Manager
強制結束AppleControlPanel.exe
,並放回C:\Windows\System32\
底下並取代掉C:\Program Files\bootcamp
下執行Bootcamp控制台(或直接重開機也可以)
,正常使用!彻底解决:Boot Camp 尝试访问启动磁盘设置时出错 的问题
底下回應是說WIN 7 x64不行。但我的MacBook Pro是2015年的,不支援WIN7。所以我是直接灌WIN 10 x64,測試可行
若不清楚手上的MacBook可安裝的windows版本,可參考以下官方資料
APPLE官網/Windows 7相容性表格
APPLE官網/Windows 10相容性表格
SQL在欄位設定中,儲存文字的char就分成這四種:
第一時間真的是不明白差距在哪!但仔細看其實還是有其規律性
char前的參數 | 說明 |
---|---|
var | 可變動。須額外花2bytes來儲存地址 |
n | 萬國碼。每一字會花2倍的空間 |
char | 長度 |
---|---|
char(n) | n Bytes |
varchar(n) | (n + 2) Bytes ,其中2Bytes用來記錄地址 |
nchar(n) | (2 × n) Bytes |
nvarchar(n) | (2 × n + 2) Bytes |
從效能來看,因char、nchar不必再確認長度,速度較快些
佔據空間上,n則會花費2倍空間
實務上,還是得根據需求選擇怎樣的格式較佳!
簡單茲分如下
需求 | 參數 |
---|---|
只有英數字、長度固定 | char |
只有英數字、長度不定 | varchar |
會含英數以外的字元、長度固定 | nchar |
會含英數以外的字元、長度不定 | nvarchar |