I'm trying to add a background using the answers from previous questions.
Sadly they don't work and return errors, either stylesheet, or the = sign, or the """.
I think it may be my location of the image? Is there something special required to store the image perhaps or something else I'm missing?
I've shown an edited down version of the code.
Thanks
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QMainWindow, QPushButton, QAction
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtCore import pyqtSlot
import os
os.chdir(r'C:\Users\Paul Hannell\python_files')
class App(QMainWindow): # Opening Window
def __init__(self):
super().__init__()
self.title = "Timelord Timer PyQt5"
self.left = 70
self.top = 100
self.width = 1170
self.height = 740
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.setWindowIcon(QIcon(r'C:\Users\Paul Hannell\python_files\Timelord.ico'))
self.statusBar().showMessage('Message in Status Bar')
label=QLabel(self)
############################
# Background Image
self.centralwidget = QWidget()
self.setCentralWidget(self.centralwidget)
lay = QHBoxLayout(self.centralwidget)
stylesheet = '''
MainWindow {
background-image: url(r'C:\Users\Paul Hannell\python_files\Running_Around4.png');
background-repeat: no-repeat;
background-position: center;
}
'''
#####################################
mainMenu = self.menuBar()
fileMenu = mainMenu.addMenu('File')
settingsMenu = mainMenu.addMenu('Settings')
resultsMenu = mainMenu.addMenu('Results')
reportsMenu = mainMenu.addMenu('Reports')
infoMenu = mainMenu.addMenu('Info')
newButton=QAction('New', self)
newButton.setStatusTip('New Race')
#newButton.triggered.connect(self.create) #This open new event options
fileMenu.addAction(newButton)
openButton = QAction('Open' , self)
openButton.setStatusTip('Open File')
#openButton.triggered.connect(self.open) # This will open existing
fileMenu.addAction(openButton)
deleteButton=QAction('Delete', self)
deleteButton.setStatusTip('Delete Race')
#deleteButton.triggered.connect(self.create) #This delete existing event.
fileMenu.addAction(deleteButton)
exitButton=QAction('Exit', self)
exitButton.setStatusTip('Exit application')
exitButton.triggered.connect(self.close)
fileMenu.addAction(exitButton)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
Your code is badly indented (and too long) so it's hard to tell, but I see several issues:
it shoud be #MainWindow in the style sheet (you're missing a #)
you need to name the App with this name: self.setObjectName('MainWindow')
you need to use setStyleSheet at some point
the url needs fixing: no quotes nor 'r'; simply the file name (maybe the space in the file name needs escaping, you could try to play with it)
This, for instance, works:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QMainWindow, QPushButton, QAction
class App(QMainWindow): # Opening Window
def __init__(self):
super().__init__()
self.setWindowTitle('hello bg')
self.setObjectName('MainWindow')
stylesheet = '''
#MainWindow {
background-image: url(/home/me/photos/DSC_0001.jpg);
background-repeat: no-repeat;
background-position: center;
}
'''
self.setStyleSheet(stylesheet)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
Related
from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QFileDialog, QPushButton, QLineEdit,QVBoxLayout, QHBoxLayout
from PyQt5.QtCore import *
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QDialog, QVBoxLayout
import Updated_encrypt
import sys
class Window(QWidget):
def __init__(self):
super().__init__()
self.title = 'Encrypt/Decrypt'
self.top = 200
self.left = 500
self.width = 400
self.height = 300
self.InitWindow()
def InitWindow(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
vbox = QVBoxLayout()
self.button1 = QPushButton('Encrypt')
self.button1.clicked.connect(self.openSecondDialog)
self.button2 = QPushButton('Decrypt')
vbox.addWidget(self.button1)
vbox.addWidget(self.button2)
self.setLayout(vbox)
self.show()
def openSecondDialog(self):
hbox = QVBoxLayout()
mydialog = QDialog(self)
mydialog.show()
self.button2 = QPushButton('Check Image')
self.button2.clicked.connect(self.getImage)
hbox.addWidget(self.button2)
self.setLayout(hbox)
self.show()
def getImage(self):
hbox = QHBoxLayout()
file_Name = QFileDialog.getOpenFileName(self,
'OpenFile',
'',
'')
image_path = file_Name[0]
updatedImage = Updated_encrypt.decrypt(image_path, 123)
pixmap = QPixmap(updatedImage)
self.label.setPixmap(QPixmap(pixmap))
self.resize(pixmap.width(), pixmap.height())
App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec())
I have my code set up to implement an algorithm to modify an image when my I select it from my pop up dialogue. What I am trying to accomplish is for the image to pop up in a separate window when I click the encrypt button. I can't seem to get anything to pop up in the separate window aside from the window itself. Any help would be appreciated.
You have at least the following errors:
The "hbox" created is being added to the window and not to the QDialog: self.setLayout(hbox), it must be mydialog.setLayout(hbox).
Do not use the same name for 2 different objects as they can cause problems, in your case there are 2 QPushButton assigned to the variable "self.button2".
You try to use the variable "self.label" but never believe it.
Considering the above we can make the following improvements:
Use more descriptive names to easily distinguish their function.
If you are going to have a window that has a different objective, it is better to create a class.
The above avoid the indicated problems, considering the above the solution is:
import sys
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import (
QApplication,
QDialog,
QFileDialog,
QHBoxLayout,
QLabel,
QPushButton,
QVBoxLayout,
QWidget,
)
import Updated_encrypt
class Dialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.load_image_btn = QPushButton("Check Image")
self.load_image_btn.clicked.connect(self.load_image)
self.image_lbl = QLabel()
lay = QVBoxLayout(self)
lay.addWidget(self.load_image_btn)
lay.addWidget(self.image_lbl)
def load_image(self):
image_path, _ = QFileDialog.getOpenFileName(self, "OpenFile", "", "")
if image_path:
updatedImage = Updated_encrypt.decrypt(image_path, 123)
pixmap = QPixmap(updatedImage)
self.image_lbl.setPixmap(QPixmap(pixmap))
class Window(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.title = "Encrypt/Decrypt"
self.InitWindow()
def InitWindow(self):
self.setWindowTitle(self.title)
self.setGeometry(200, 500, 400, 300)
self.encrypt_btn = QPushButton("Encrypt")
self.encrypt_btn.clicked.connect(self.openSecondDialog)
self.decrypt_btn = QPushButton("Decrypt")
vbox = QVBoxLayout(self)
vbox.addWidget(self.encrypt_btn)
vbox.addWidget(self.decrypt_btn)
def openSecondDialog(self):
dialog = Dialog(self)
dialog.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec())
In my QMainWindow, I have a QFrame and a QWidget that wraps a QQuickView and displays the ui through a qml file.
I am trying to implement a drag and drop functionality where, on mouse-down and mouse-move in the QFrame, a thumbnail follows the cursor's position throughout until mouse-release. The mouse-release will happen within QQuickView.
The hover event within QQuickView has no issues and I can successfully get the hover event. The problem arises when on mouse-down within QFrame followed by a mouse-move into QQuickView, I am unable to get any mouse events in QQuickView.
On the left is the QFrame and the right is the QQuickView.
Hovering in QQuickView independently:
Mouse-down in QFrame and mouse-move into QQuickView:
Any mouse events can only be captured after mouse-release.
These are what I have written so far:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QFrame, QLabel, QGridLayout, QVBoxLayout
from PyQt5.QtCore import Qt, QMimeData, QUrl
from PyQt5.QtGui import QDrag, QPixmap
from PyQt5.QtQuick import QQuickView
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.centralWidget = QWidget(self)
gridlayout = QGridLayout(self.centralWidget)
gridlayout.setContentsMargins(0,0,0,0)
gridlayout.setHorizontalSpacing(0)
gridlayout.setVerticalSpacing(0)
self.setCentralWidget(self.centralWidget)
self.leftPanel = QVBoxLayout()
self.rightPanel = QVBoxLayout()
gridlayout.addLayout(self.leftPanel, 0, 0, 1, 1)
gridlayout.addLayout(self.rightPanel, 0, 1, 1, 1)
gridlayout.setSpacing(0)
self.setStyleSheet("background:grey")
self.resize(300, 200)
self.show()
class Left(QFrame):
def __init__(self):
super().__init__()
self.resize(500, 500)
self.label = QLabel(self)
self.label.resize(50, 50)
def mouseMoveEvent(self, e):
mimeData = QMimeData()
drag = QDrag(self)
self.thumbnail = QPixmap('./test.png').scaled(50, 50, Qt.KeepAspectRatio)
drag.setPixmap(self.thumbnail)
drag.setMimeData(mimeData)
drag.exec_(Qt.MoveAction)
class Right(QQuickView):
def __init__(self, parent=None):
super().__init__(parent)
self.rootContext().setContextProperty('Right', self)
self.setSource(QUrl('./drag.qml'))
self.setMinimumHeight(200)
self.setMinimumWidth(150)
if __name__ == '__main__':
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.leftPanel.addWidget(Left())
main_window.rightPanel.addWidget(QWidget.createWindowContainer(Right()))
app.exec_()
Based on what I have read from different sources and the Qt documentation, I suppose I have to forward the events from the QFrame to the QQuickView or there seems to be some form of global mouse events to be handled.
How can I go about achieving this?
turns out i was using the wrong qml element. DropArea should have been used in the qml.
import QtQuick 2.7
Rectangle {
id: root
anchors.fill: parent
color: 'transparent'
Column {
anchors.centerIn: parent
Rectangle {
width: 50
height: 50
color: 'red'
anchors.horizontalCenter: parent.horizontalCenter
DropArea {
anchors.fill: parent
onEntered: parent.color = 'blue'
onExited: parent.color = 'red'
onDropped: console.log('triggger this thing yo')
}
}
Text {
width: parent.parent.width
text: 'on hover over box, color changes from red to blue and vice versa when hover out'
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
}
}
}
hope this will be able to help someone out down the road. credits to raven-worx on Qt Forum for the solution.
I've been looking through answers for a while but couldn't find a solution to my problem. I recently started playing around with PyQt and trying to code out couple of ideas, one of which was to have a couple of buttons with some text on them and when a button is clicked, its text would change color. Here is my code:
import sys
from PyQt5 import QtWidgets, QtGui
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QLabel, QMainWindow,
QHBoxLayout, QGroupBox, QDialog, QVBoxLayout, QGridLayout, QMessageBox)
from PyQt5.QtCore import pyqtSlot, Qt
class App(QDialog):
def __init__(self):
super().__init__()
self.title = "Battleship"
self.left = 50
self.top = 50
self.width = 750
self.height = 500
self.initUI()
def initUI(self):
self.setGeometry(self.left, self.top, self.width, self.height)
self.setWindowTitle(self.title)
self.setFixedSize(self.width, self.height)
stylesheet = """QPushButton {background: #EEE; color: #11}
!QPushButton {background: #555; color: #EEE}"""
self.setStyleSheet(stylesheet)
self.grid()
layout = QVBoxLayout()
layout.addWidget(self.box)
self.setLayout(layout)
self.show()
def grid(self):
self.box = QGroupBox()
self.layout = QGridLayout()
self.box.setLayout(self.layout)
self.button1 = QPushButton('X', self)
self.button2 = QPushButton('X', self)
self.button3 = QPushButton('X', self)
self.button1.clicked.connect(self.pick)
self.button2.clicked.connect(self.pick)
self.button3.clicked.connect(self.pick)
self.layout.addWidget(self.button1)
self.layout.addWidget(self.button2)
self.layout.addWidget(self.button3)
def pick(self):
# turn 'X' from black to red ONLY on the clicked button
# while leaving the others untouched
pass
#---------------------------------------------------------------
if __name__ == '__main__':
app = QApplication(sys.argv)
gui = App()
sys.exit(app.exec_())
What does the 'pick' function have to look like in order to do this? To clarify: I don't want to make three individual functions, one for each button (as it would be very impractical for a larger number of buttons), but a single function which would work with any button.
the sender() method returns us the object that emits the signal, in your case the button will be pressed:
def pick(self):
# turn 'X' from black to red ONLY on the clicked button
# while leaving the others untouched
btn = self.sender()
btn.setStyleSheet("color: red")
I am trying to create a pop-up window that gets popped-up from pressing on a QPushButton. However, I have a separate QPushButton class that I would like to use. I can't seem to get it working. Anything I am doing wrong?
#import ... statements
import sys
# from ... import ... statements
from PyQt5.QtWidgets import (QMainWindow, QApplication, QPushButton, QGridLayout, QWidget, QHBoxLayout, QLabel,
QVBoxLayout)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont, QFontDatabase, QColor, QPalette, QMovie
from skimage import transform, io
# Create main window of the widget
class MainWindow(QWidget):
def __init__(self):
super().__init__()
#Set a title inside the widget
self.titleLabel = QLabel()
titleText = "some title text"
self.titleLabel.setText(titleText)
# Give the label some flair
self.titleLabel.setFixedWidth(1000)
self.titleLabel.setAlignment(Qt.AlignCenter)
QFontDatabase.addApplicationFont(link_to_custom_font)
font = QFont()
font.setFamily("custom_font_name")
font.setPixelSize(50)
self.titleLabel.setFont(font)
# Set first button - The "Yes" Button
self.btn1 = myButtonOne("Yes")
#Initialize GUI
self.layoutGUI()
self.initUI()
def initUI(self):
self.fromleft = 200
self.fromtop = 100
self.w = 1000
self.h = 500
self.setGeometry(self.fromleft, self.fromtop, self.w, self.h)
def layoutGUI(self):
hbox = QHBoxLayout()
hbox.setSpacing(20)
hbox.addWidget(self.btn1)
vbox = QVBoxLayout()
vbox.addWidget(self.titleLabel)
vbox.addLayout(hbox)
self.setLayout(vbox)
class myButtonOne(QPushButton):
def __init__(self, parent=None):
super(myButtonOne, self).__init__(parent)
# Set maximum border size
imSize = io.imread(imagePath)
imHeight = imSize.shape[1]
imWidth = imSize.shape[0]
# Set first button - The "Yes" Button
yesImage = someImagePath
self.setStyleSheet("background-image: url(" + yesImage + ");"
"background-repeat: none;"
"background-position: center;"
"border: none")
self.setFixedSize(imWidth, imHeight)
self.clicked.connect(self.buttonOnePushed)
def buttonOnePushed(self):
textView().show()
def enterEvent(self, event):
newImage = someOtherImagePath
self.setStyleSheet("background-image: url("+newImage+");"
"background-repeat: none;"
"background-position: center;"
"border: none")
def leaveEvent(self, event):
newImage = someImagePath
self.setStyleSheet("background-image: url("+newImage+");"
"background-repeat: none;"
"background-position: center;"
"border: none")
class textView(QWidget):
def __init(self):
textView.__init__()
theText = QLabel()
#define sizes
self.height = 550
self.width = 250
# Open QWidget
self.initUI()
# Set the text for the QLabel
someText = "Some Text for the label"
theText.setText(someText)
def initUI(self):
self.show()
# Start GUI
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
So, I am trying to keep the QPushButton classes separate, so that I can customize them. I would like to keep it like that, especially to keep it clean and readable.
First off - please read: How to create a Minimal, Complete, and Verifiable example. I had a lot of work minimizing your code, which wasted a good amount of my time.
Nonetheless, here is a minimal working code, with your own button class:
import sys
from PyQt5.QtWidgets import QApplication, QPushButton, QWidget, QLabel, QVBoxLayout
class MainWindow(QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.titleLabel = QLabel( "some label text" )
self.btn1 = myButtonOne( "button text" )
hbox = QVBoxLayout() # one vertical box seemed enough
hbox.addWidget( self.titleLabel )
hbox.addWidget( self.btn1 )
self.setLayout( hbox )
class myButtonOne(QPushButton):
def __init__(self, text, parent=None):
super(myButtonOne, self).__init__(text, parent)
self.clicked.connect(self.buttonOnePushed)
# add your customizations here
def buttonOnePushed (self) :
self.t = textView()
self.t.show()
class textView(QWidget):
def __init__(self):
super(textView, self).__init__()
self.theText = QLabel('test', self )
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
What have you done wrong in your code?
using textView().show() creates a local version of you textView-class and show()'s it:
def buttonOnePushed(self):
textView().show()
But, show() means that the code continues, where the end of your code comes, which results in cleaning up the locals. End - it's just shown for a microsecond.
def buttonOnePushed (self) :
self.t = textView()
self.t.show()
The code above stores the var as instance-attribute of the button, which is not cleaned up.
Furthermore you misspelled the init in your textView-class:
"__init" should be __init__ - else it is not called when using the constructor:
class textView(QWidget):
def __init(self):
textView.__init__()
Finally, you wanted to called show() twice:
in your textView-init you call initUI() which is calling show()
you calling show manually with textView().show()
Hope this helps! I did not include your personal style adjustments for readability.
I've found an example that changing a QPushButton's icon when mouse is hover on it. I tried to convert it to my codes, but there are some problems. First check the example I found, it's really short. http://paste.ubuntu.com/17302717/
These codes changing the icon of button if mouse is on it. Here is my codes that raises error
return QPushButton.mouseMoveEvent(QPushButton, event)
TypeError: QPushButton.mouseMoveEvent(QMouseEvent): first argument of unbound method must have type 'QPushButton'
from PyQt5.QtWidgets import QApplication,QPushButton,QWidget
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QSize
import PyQt5.QtWidgets,PyQt5.QtCore,sys
class cssden(QMainWindow):
def __init__(self):
super().__init__()
self.mwidget = QMainWindow(self)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.setMouseTracking(True)
self.setFixedSize(1400,923)
#Button
self.mbutton = QPushButton(self)
self.mbutton.setStyleSheet("background-color: rgb(30,30,30);"
"background-image: url('resources/twitter-logo.png');"
"border: 3px solid black;"
"background-position: center;"
)
self.mbutton.setGeometry(2,300,110,60)
self.mbutton.clicked.connect(self.yaz)
self.show()
def mouseMoveEvent(self, event):
if event.pos().x()>self.mbutton.width()-10 or event.pos().y()>self.mbutton.height()-10\
or event.pos().x() < 10 or event.pos().y()< 10:
bmp = QIcon("1.png")
self.mbutton.setIcon(bmp)
else:
bmp = QIcon('2.png')
self.mbutton.setIcon(bmp)
self.mbutton.setIconSize(QSize(200,200))
return QPushButton.mouseMoveEvent(self, event)
def yaz(self):
print ("button pressed")
app = QApplication(sys.argv)
app.setStyleSheet("QMainWindow{background-color: rgb(30,30,30);border: 2px solid rgb(20,20,20)}")
ex = cssden()
sys.exit(app.exec_())
I don't understand where is the problem. I tried to change return QPushButton.mouseMoveEvent(self, event) to return QPushButton.mouseMoveEvent(QPushButton, event) and other versions, but not worked. What I'm missing, how can I fix this?
EDIT: I changed self.setMouseTracking(True) to self.mbutton.setMouseTracking(True) and no error now, but icon is not changing anyway. Why the icon is not changing?
Your code has a few problems, namely with imports. The main problem though is that you don't need this: return QPushButton.mouseMoveEvent(self, event)
Try the following corrections to your code:
from PyQt5.QtWidgets import QApplication,QPushButton,QWidget from
PyQt5.QtGui import QIcon from PyQt5.QtCore import QSize from PyQt5
import QtCore, QtWidgets, QtGui
import PyQt5.QtWidgets,PyQt5.QtCore,sys
class cssden(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
# self.mwidget = QMainWindow(self)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.setMouseTracking(True)
self.setFixedSize(1400,923)
#Button
self.mbutton = QPushButton(self)
self.mbutton.setStyleSheet("background-color: rgb(30,30,30);"
"background-image: url('resources/twitter-logo.png');"
"border: 3px solid black;"
"background-position: center;"
)
self.mbutton.setGeometry(2,300,110,60)
self.mbutton.clicked.connect(self.yaz)
self.show()
def mouseMoveEvent(self, event):
if event.pos().x()>self.mbutton.width()-10 or event.pos().y()>self.mbutton.height()-10\
or event.pos().x() < 10 or event.pos().y()< 10:
bmp = QIcon("1.png")
self.mbutton.setIcon(bmp)
else:
print(1)
bmp = QIcon('2.png')
self.mbutton.setIcon(bmp)
self.mbutton.setIconSize(QSize(200,200))
# return self.mbutton.mouseMoveEvent(event)
def yaz(self):
print ("button pressed")
app = QApplication(sys.argv)
app.setStyleSheet("QMainWindow{background-color:
rgb(30,30,30);border: 2px solid rgb(20,20,20)}")
ex = cssden() sys.exit(app.exec_())
In any case, I don't really understood what you are trying to achieve. If you need to create some kind of hover effect to your button there are other, much better ways. For example this one:
from PyQt5.QtWidgets import QApplication,QPushButton,QWidget
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QSize
from PyQt5 import QtCore, QtWidgets, QtGui
import PyQt5.QtWidgets,PyQt5.QtCore,sys
class HoverButton(QPushButton):
mouseHover = QtCore.pyqtSignal(bool)
def __init__(self, parent=None):
QPushButton.__init__(self, parent)
self.setMouseTracking(True)
def enterEvent(self, event):
self.mouseHover.emit(True)
bmp = QIcon("1.png")
self.setIcon(bmp)
self.setIconSize(QSize(200,200))
def leaveEvent(self, event):
self.mouseHover.emit(False)
bmp = QIcon("2.png")
self.setIcon(bmp)
self.setIconSize(QSize(200,200))
class cssden(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
# self.mwidget = QMainWindow(self)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.setMouseTracking(True)
self.setFixedSize(1400, 923)
#Button
self.mbutton = HoverButton(self)
self.mbutton.setStyleSheet("background-color: rgb(30,30,30);"
"background-image: url('resources/twitter-logo.png');"
"border: 3px solid black;"
"background-position: center;"
)
self.mbutton.setGeometry(2,300,110,60)
self.mbutton.clicked.connect(self.yaz)
self.show()
def yaz(self):
print("button pressed")
app = QApplication(sys.argv)
app.setStyleSheet("QMainWindow{background-color: rgb(30,30,30);border: 2px solid rgb(20,20,20)}")
ex = cssden()
sys.exit(app.exec_())
I would advise the following answers:
PyQT how to make a QEvent.Enter on QPushbutton? (my solution is based on this method)
Pyqt Mouse hovering on a QPushButton