2015-11-29 41 views
6

Voglio creare una finestra a tutto schermo con sfondo semitrasparente, ma widget per bambini completamente visibili (tipo effetto di sovrapposizione).PyQt5: Crea una finestra semitrasparente con bambini non trasparenti

Ecco quello che ho finora:

import sys 

from PyQt5.QtCore import * 
from PyQt5.QtGui import * 
from PyQt5.QtWidgets import * 

app = QApplication(sys.argv) 

# Create the main window 
window = QMainWindow() 

window.setWindowOpacity(0.3) 
window.setAttribute(Qt.WA_NoSystemBackground, True) 
window.setWindowFlags(Qt.FramelessWindowHint) 

# Create the button 
pushButton = QPushButton(window) 
pushButton.setGeometry(QRect(240, 190, 90, 31)) 
pushButton.setText("Finished") 
pushButton.clicked.connect(app.quit) 

# Center the button 
qr = pushButton.frameGeometry() 
cp = QDesktopWidget().availableGeometry().center() 
qr.moveCenter(cp) 
pushButton.move(qr.topLeft()) 

# Run the application 
window.showFullScreen() 
sys.exit(app.exec_()) 

Questo crea un effetto semi-trasparente, ma anche il pulsante è semi-trasparente.

Ho anche cercato di sostituire il

window.setWindowOpacity(0.3) 

con questa chiamata

window.setAttribute(Qt.WA_TranslucentBackground, True) 

ma inutilmente, in questo caso il fondo era completamente trasparente (quando il pulsante è stato correttamente completamente visibile).

Soluzione: (implementati grazie al suggerimento di Aaron):

Il trucco sta nella realizzazione di un paintEvent personalizzato per la finestra principale.

import sys 

from PyQt5.QtCore import * 
from PyQt5.QtGui import * 
from PyQt5.QtWidgets import * 

class CustomWindow(QMainWindow): 
    def paintEvent(self, event=None): 
     painter = QPainter(self) 

     painter.setOpacity(0.7) 
     painter.setBrush(Qt.white) 
     painter.setPen(QPen(Qt.white)) 
     painter.drawRect(self.rect()) 


app = QApplication(sys.argv) 

# Create the main window 
window = CustomWindow() 

window.setWindowFlags(Qt.FramelessWindowHint) 
window.setAttribute(Qt.WA_NoSystemBackground, True) 
window.setAttribute(Qt.WA_TranslucentBackground, True) 

# Create the button 
pushButton = QPushButton(window) 
pushButton.setGeometry(QRect(240, 190, 90, 31)) 
pushButton.setText("Finished") 
pushButton.clicked.connect(app.quit) 

# Center the button 
qr = pushButton.frameGeometry() 
cp = QDesktopWidget().availableGeometry().center() 
qr.moveCenter(cp) 
pushButton.move(qr.topLeft()) 

# Run the application 
window.showFullScreen() 
sys.exit(app.exec_()) 

risposta

4

Ok, quando viene non sembra funzionare con le bandiere disponibili è comunque possibile utilizzare Qt.WA_TranslucentBackground perché è possibile disegnare un rettangolo semitranparent su che la trasparenza.

Ricavate la vostra finestra principale da QMainWindow e utilizzate invece quella classe.

Applicare self.setAttribute(Qt.WA_TranslucentBackground, True) a quella classe

Implementare il paintEvent della classe MainWindow come questo (simile, potrebbe contenere degli errori, ma il principio dovrebbe funzionare):

QPixmap canvas(rect()) 

canvas.fill(Qt.transparent) # fill transparent (makes alpha channel available) 

QPainter p(canvas)   # draw on the canvas 
p.setOpacity(0.3) 
p.setBrush(QBrush(Qt.white)) # use the color you like 
p.setPen(QPen(Qt.transparen)) 

p.drawRect(rect()) # draws the canvas with desired opacity 

p.start(self)  # now draw on the window itself 
p.drawPixmap(rect(), canvas) 
+0

ciò che accade è che il pulsante è ancora semitrasparente e lo sfondo viene impostato con un colore definito dal sistema (anziché nero, ora è bianco). Non sono sicuro che setWindowOpacity funzioni su widget non finestra. – Enuy

+0

Modificato la mia risposta. A volte lo facevo così e funzionava sempre quando ne hai bisogno. – Aaron

+0

Ok, proverò a convertire questo pseudocodice QT in PyQT e vedere come funziona. – Enuy