搜索了很多文章,有關(guān)于Qt的C++版本無邊框窗口的拖動(dòng):
例如這篇《Qt 無標(biāo)題無邊框程序的拖動(dòng)和改變大小》http://blog.csdn.net/kfbyj/article/details/9284923
其中主要講到兩種方法,但是PyQt(Qt的Python版本)實(shí)現(xiàn)就沒有找到,以下主要講PyQt4中的實(shí)現(xiàn)
方法1:在QWidget/QDialog中重寫mousePRessEvent和mouseMoveEvent方法,利用move方法移動(dòng)窗口
這種方法相對簡單,但是缺陷在于會(huì)在鼠標(biāo)按下移動(dòng)過程中,整個(gè)窗口是實(shí)時(shí)移動(dòng),實(shí)時(shí)重繪,移動(dòng)快了會(huì)出現(xiàn)重影(由于多次重繪)。
#!/usr/bin/python #-*-coding:utf-8-*-from PyQt4.QtGui import *from PyQt4.Qt import *from PyQt4.QtCore import *class AboutUsDialog(QDialog): def __init__(self, parent=None): super(AboutUsDialog, self).__init__(parent) self.setWindowFlags(Qt.FramelessWindowHint | Qt.Dialog) def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.dragPosition = event.globalPos() - self.frameGeometry().topLeft() Qapplication.postEvent(self, QEvent(174)) event.accept() def mouseMoveEvent(self, event): if event.buttons() == Qt.LeftButton: self.move(event.globalPos() - self.dragPosition) event.accept() if __name__ == '__main__': import sys app = QApplication(sys.argv) aboutus = AboutUsDialog() aboutus.show() sys.exit(app.exec_())
而正常的windows窗體移動(dòng)都會(huì)在鼠標(biāo)按下后呈現(xiàn)虛線邊框,只移動(dòng)虛線邊框,鼠標(biāo)放開后才會(huì)將窗體真正移動(dòng)
方法二:使用winEvent處理消息,將鼠標(biāo)點(diǎn)擊窗體內(nèi)的事件WM_NCHITTEST,模擬成為點(diǎn)擊原生標(biāo)題欄的事件HTCAPTION。在無邊框的窗口中增加isInTitle方法來判斷鼠標(biāo)位置是否在窗口中自定義的標(biāo)題欄中。
此方法可以實(shí)現(xiàn)鼠標(biāo)在自定義欄中的鼠標(biāo)拖動(dòng),但是暫時(shí)不支持鼠標(biāo)雙擊進(jìn)行最大化切換和還原。
#!/usr/bin/python #-*-coding:utf-8-*-from PyQt4.QtGui import *from PyQt4.Qt import *from PyQt4.QtCore import *class AboutUsDialog(QWidget): def __init__(self, parent=None): super(AboutUsDialog, self).__init__(parent) self.setWindowFlags(Qt.FramelessWindowHint | Qt.Dialog) def isInTitle(self, xPos, yPos): return yPos < 30 class MyApplication(QApplication): def __init__(self, args): super(MyApplication, self).__init__(args) def GET_X_LPARAM(self, param): #define LOWord(l) ((WORD)((DWORD_PTR)(l) & 0xffff)) #define HIWORD(l) ((WORD)((DWORD_PTR)(l) >> 16)) #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) return param & 0xffff def GET_Y_LPARAM(self, param): return param >> 16 def winEventFilter(self, msg): if msg.message == 0x84: #WM_NCHITTEST form = self.activeWindow() if form: xPos = self.GET_X_LPARAM(msg.lParam) - form.frameGeometry().x() yPos = self.GET_Y_LPARAM(msg.lParam) - form.frameGeometry().y()# 鼠標(biāo)在窗體自定義標(biāo)題范圍內(nèi),窗體自定義一個(gè)isInTitle的方法判斷 # if yPos < 30 and xPos < 456: if not form.isMaximized() and hasattr(form, 'isInTitle') and form.isInTitle(xPos, yPos): return True, 0x2 #HTCAPTION return False, 0 if __name__ == '__main__': import sys app = MyApplication(sys.argv) aboutus = AboutUsDialog() aboutus.showNormal() sys.exit(app.exec_())
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注