Hi everyone.
I am making a GUI application using python3.4, PyQt5 in windows 7.
Application is very sample. User clicks a main window's button, information dialog pops up. And when a user clicks information dialog's close button (window's X button), system shows confirm message. This is all.
Here's my code.
# coding: utf-8
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QDialog, QLabel
class mainClass(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
openDlgBtn = QPushButton("openDlg", self)
openDlgBtn.clicked.connect(self.openChildDialog)
openDlgBtn.move(50, 50)
self.setGeometry(100, 100, 200, 200)
self.show()
def openChildDialog(self):
childDlg = QDialog(self)
childDlgLabel = QLabel("Child dialog", childDlg)
childDlg.resize(100, 100)
childDlg.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
mc = mainClass()
sys.exit(app.exec_())
Result screen shot is...
In this situation, I've added these code in mainClass class.
def closeEvent(self, event):
print("X is clicked")
This code works only when the main window is closed. But what I want is closeEvent function works when childDlg is to closed. Not main window.
What should I do?
You have added, the method closeEvent in the class mainClass.
So you have reimplemented the method closeEvent of your QMainwindow and not the method closeEvent of your childDlg. To do it, you have to subclass your chilDlg like this:
# coding: utf-8
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QDialog, QLabel
class ChildDlg(QDialog):
def closeEvent(self, event):
print("X is clicked")
class mainClass(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
openDlgBtn = QPushButton("openDlg", self)
openDlgBtn.clicked.connect(self.openChildDialog)
openDlgBtn.move(50, 50)
self.setGeometry(100, 100, 200, 200)
self.show()
def openChildDialog(self):
childDlg = ChildDlg(self)
childDlgLabel = QLabel("Child dialog", childDlg)
childDlg.resize(100, 100)
childDlg.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
mc = mainClass()
sys.exit(app.exec_())
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QDialog, QLabel
class mainClass(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
openDlgBtn = QPushButton("openDlg", self)
openDlgBtn.clicked.connect(self.openChildDialog)
openDlgBtn.move(50, 50)
self.setGeometry(100, 100, 200, 200)
self.show()
def openChildDialog(self):
childDlg = QDialog(self)
childDlgLabel = QLabel("Child dialog", childDlg)
childDlg.closeEvent = self.CloseEvent
childDlg.resize(100, 100)
childDlg.show()
def CloseEvent(self, event):
print("X is clicked")
if __name__ == "__main__":
app = QApplication(sys.argv)
mc = mainClass()
sys.exit(app.exec_())
Related
Here's my attempt at making this work:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QTextEdit
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
class App(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.on_click()
def initUI(self):
button = QPushButton('PyQt5 button', self)
button.move(100,200)
button.clicked.connect(self.on_click)
def on_click(self):
text = QTextEdit(self)
insideText = "Text"
text.document().setPlainText(insideText)
text.resize(100,25)
print('PyQt5 button click')
position = text.pos()
text.move(position.x()+50,position.y()+0)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())
Maybe I need to make the QTextEdit go somewhere in the initUI() method, instead of being defined in on_click(). I already tried this but I get "text is not defined", and I'm not sure how to reference it inside another function/method. Any help is appreciated.
Edit: Here's the working code:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton,QTextEdit
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
class App(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.on_click()
def initUI(self):
self.button = QPushButton('PyQt5 button', self)
self.button.move(100,200)
self.button.clicked.connect(self.on_click)
self.text = QTextEdit(self)
insideText = "Text"
self.text.document().setPlainText(insideText)
self.text.resize(100,25)
def on_click(self):
print('PyQt5 button click')
position = self.text.pos()
self.text.move(position.x()+50,position.y()+0)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())
I want to implement behaviour of a popup-window exactly like default volume controller in windows 10. One click on icon, window opens or closes; if window is opened, clicking outside it will close the window. How can i implement this?
Before, i found that it is possible for the widget to override the methods for pressing and releasing the mouse keys, but here it was not found, or it was poorly searched. Help me please.
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QGridLayout, \
QWidget, QSystemTrayIcon, QStyle, qApp
import PyQt5.QtCore
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setMinimumSize(PyQt5.QtCore.QSize(600, 130))
self.setMaximumSize(PyQt5.QtCore.QSize(600, 130))
self.setWindowFlags(PyQt5.QtCore.Qt.Popup)
screen_geometry = QApplication.desktop().availableGeometry()
screen_size = (screen_geometry.width(), screen_geometry.height())
win_size = (self.frameSize().width(), self.frameSize().height())
x = screen_size[0] - win_size[0]
y = screen_size[1] - win_size[1]
self.move(x, y)
self.setWindowOpacity(0.85)
self.setWindowTitle("System Tray Application")
central_widget = QWidget(self)
self.setCentralWidget(central_widget)
grid_layout = QGridLayout(central_widget)
grid_layout.addWidget(QLabel("Application, which can minimize to tray",
self), 0, 0)
self.tray_icon = QSystemTrayIcon(self)
self.tray_icon.setIcon(self.
style().standardIcon(QStyle.SP_ComputerIcon))
self.tray_icon.activated.connect(self.trigger)
self.tray_icon.show()
self.setGeometry(500, 570, 600, 130)
self.fl = False
def trigger(self, reason):
if reason == QSystemTrayIcon.MiddleClick:
qApp.quit()
elif reason == QSystemTrayIcon.Trigger:
if not self.fl:
self.show()
else:
self.hide()
self.fl = not self.fl
elif reason == 1:
self.fl = False
# def mouseReleaseEvent(self, event):
# self.hide()
# self.fl = False
if __name__ == "__main__":
app = QApplication(sys.argv)
mw = MainWindow()
mw.show()
sys.exit(app.exec())
If you want to toggle visibility then you must use the setVisible() and isVisible() methods:
import sys
from PyQt5.QtWidgets import (
QApplication,
QGridLayout,
QLabel,
QMainWindow,
QStyle,
QSystemTrayIcon,
QWidget,
)
from PyQt5.QtCore import Qt, QSize
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setFixedSize(600, 130)
self.setWindowFlag(Qt.Popup)
self.setWindowOpacity(0.85)
self.setWindowTitle("System Tray Application")
central_widget = QWidget()
self.setCentralWidget(central_widget)
grid_layout = QGridLayout(central_widget)
grid_layout.addWidget(QLabel("Application, which can minimize to tray"), 0, 0)
self.tray_icon = QSystemTrayIcon(self)
self.tray_icon.setIcon(self.style().standardIcon(QStyle.SP_ComputerIcon))
self.tray_icon.activated.connect(self.trigger)
self.tray_icon.show()
self.setGeometry(
QStyle.alignedRect(
Qt.LeftToRight,
Qt.AlignBottom | Qt.AlignRight,
self.window().size(),
QApplication.desktop().availableGeometry(),
)
)
def trigger(self, reason):
if reason == QSystemTrayIcon.MiddleClick:
QApplication.quit()
elif reason == QSystemTrayIcon.Trigger:
self.setVisible(not self.isVisible())
if __name__ == "__main__":
app = QApplication(sys.argv)
mw = MainWindow()
mw.show()
sys.exit(app.exec())
I'm trying to write a Python program using PyQt5 that will display a window in each iteration of the for loop. I would like to close after incrementing and displaying the next window. However, I do not know how to stop the loop every iteration and at the moment I am getting 6 windows at once.
main.py
import sys
from PyQt5.QtWidgets import (QLineEdit, QVBoxLayout, QMainWindow,
QWidget, QDesktopWidget, QApplication, QPushButton, QLabel,
QComboBox, QFileDialog, QRadioButton)
from PyQt5.QtCore import pyqtSlot, QByteArray
from alert import Window2
from test import test
class SG(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.resize(300, 150)
self.setWindowTitle('TEST')
self.resultsGen = QPushButton('TEST', self)
self.resultsGen.clicked.connect(lambda: self.on_click())
self.show()
#pyqtSlot()
def on_click(self):
test(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
sg = SG()
sys.exit(app.exec_())
alert.py
from PyQt5.QtWidgets import (QLineEdit, QVBoxLayout, QMainWindow,
QWidget, QDesktopWidget, QApplication, QPushButton, QLabel,
QComboBox, QFileDialog, QRadioButton)
from PyQt5.QtCore import pyqtSlot, QByteArray
from PyQt5.QtGui import QPixmap
from PyQt5 import QtGui, QtCore
class Window2(QMainWindow):
def __init__(self):
super().__init__()
self.initPopup()
def initPopup(self):
self.resize(500, 500)
self.setWindowTitle("Window22222")
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
lay = QVBoxLayout(self.central_widget)
label = QLabel(self)
pixmap = QPixmap('cropped/8.png')
label.setPixmap(pixmap)
self.resize(pixmap.width(), pixmap.height())
lay.addWidget(label)
self.textbox = QLineEdit(self)
self.textbox.move(20, 20)
self.textbox.resize(280, 40)
# Create a button in the window
self.button = QPushButton('Show text', self)
self.button.move(20, 80)
# connect button to function on_click
self.button.clicked.connect(lambda: self.on_clickX())
self.show()
#pyqtSlot()
def on_clickX(self):
textboxValue = self.textbox.text()
print(textboxValue)
self.textbox.setText("")
self.hide()
test.py
from alert import Window2
def test(self):
for x in range(6):
w = Window2()
As soon as you run the for cycle, all the code of the initialization will be executed, which includes the show() call you used at the end of initPopup().
A simple solution is to create a new signal that is emitted whenever you hide a window, and connect that signal to a function that creates a new one until it reaches the maximum number.
main.py:
import sys
from PyQt5.QtWidgets import QWidget, QApplication, QPushButton
from alert import Window2
class SG(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.alerts = []
def initUI(self):
self.resize(300, 150)
self.setWindowTitle('TEST')
self.resultsGen = QPushButton('TEST', self)
self.resultsGen.clicked.connect(self.nextAlert)
self.show()
def nextAlert(self):
if len(self.alerts) >= 6:
return
alert = Window2()
self.alerts.append(alert)
alert.setWindowTitle('Window {}'.format(len(self.alerts)))
alert.closed.connect(self.nextAlert)
alert.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
sg = SG()
sys.exit(app.exec_())
alert.py:
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class Window2(QMainWindow):
closed = pyqtSignal()
def __init__(self):
super().__init__()
self.initPopup()
def initPopup(self):
self.resize(500, 500)
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
lay = QVBoxLayout(self.central_widget)
label = QLabel(self)
pixmap = QPixmap('cropped/8.png')
label.setPixmap(pixmap)
self.resize(pixmap.width(), pixmap.height())
lay.addWidget(label)
self.textbox = QLineEdit(self)
lay.addWidget(self.textbox)
# Create a button in the window
self.button = QPushButton('Show text', self)
lay.addWidget(self.button)
# connect button to function on_click
self.button.clicked.connect(lambda: self.on_clickX())
self.show()
#pyqtSlot()
def on_clickX(self):
textboxValue = self.textbox.text()
print(textboxValue)
self.textbox.setText("")
self.hide()
self.closed.emit()
Just note that with this very simplified example the user might click on the button of the "SG" widget even if an "alert" window is visibile. You might prefer to use a QDialog instead of a QMainWindow and make the main widget a parent of that dialog.
main.py:
class SG(QWidget):
# ...
def nextAlert(self):
if len(self.alerts) >= 6:
return
alert = Window2(self)
# ...
alert.py:
class Window2(QDialog):
closed = pyqtSignal()
def __init__(self, parent):
super().__init__()
self.initPopup()
def initPopup(self):
self.resize(500, 500)
# a QDialog doesn't need a central widget
lay = QVBoxLayout(self)
# ...
Also, if an alert window is closed using the "X" button the new one will not be shown automatically. To avoid that, you can implement the "closeEvent" and ignore the event, so that the user will not be able to close the window until the button is clicked. As QDialogs can close themself when pressing the escape key, I'm also ignoring that situation.
alert.py:
class Window2(QMainWindow):
# ...
def closeEvent(self, event):
event.ignore()
def keyPressEvent(self, event):
if event.key() != Qt.Key_Escape:
super().keyPressEvent(event)
I'm trying to capture Text with a click on a QPushButton and Display it in a QLabel with pyqt5
I really new to this stuff so go easy on me !
here is the code I have so far:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton, QLabel, QLineEdit
from PyQt5.QtCore import pyqtSlot
class Window(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
hbox = QHBoxLayout()
game_name = QLabel("Game Name:", self)
game_line_edit = QLineEdit(self)
search_button = QPushButton("Search", self)
search_button.clicked.connect(self.on_click)
hbox.addWidget(game_name)
hbox.addWidget(game_line_edit)
hbox.addWidget(search_button)
self.setLayout(hbox)
self.show()
#pyqtSlot()
def on_click(self):
game = QLabel(game_line_edit.text(), self)
hbox.addWidget(game)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Window()
sys.exit(app.exec_())
I keep getting this error:
game = QLabel(game_line_edit.text(), self)
NameError: name 'game_line_edit' is not defined
I am not sure why game_line_edit is not defined but have a feeling it's because it not is the same "class" as my on_click class but am not sure
any help would be appreciated
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton, QLabel, QLineEdit
from PyQt5.QtCore import pyqtSlot
class Window(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.hbox = QHBoxLayout()
self.game_name = QLabel("Game Name:", self)
self.game_line_edit = QLineEdit(self)
self.search_button = QPushButton("Search", self)
self.search_button.clicked.connect(self.on_click)
self.hbox.addWidget(self.game_name)
self.hbox.addWidget(self.game_line_edit)
self.hbox.addWidget(self.search_button)
self.setLayout(self.hbox)
self.show()
#pyqtSlot()
def on_click(self):
game = QLabel(self.game_line_edit.text(), self)
self.hbox.addWidget(game)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Window()
sys.exit(app.exec_())
I understand that to use a global variable from a function, you Need to execute the function first:
def f():
global s
s = 'Hello'
f()
print(s)
But how do I use variable s globally in following example:
import sys
from PyQt4.QtGui import QApplication, QMainWindow, QPushButton, QLineEdit, QLabel, QComboBox, QProgressBar, QFileDialog
from PyQt4.QtCore import QSize, pyqtSlot
class App(QMainWindow):
def __init__(self):
super(App, self).__init__()
self.setGeometry(500, 300, 820, 350)
self.setWindowTitle("Widget")
self.initUI()
def initUI(self):
#Buttons
btnposx = 30
btnposy = 50
self.btn4 = QPushButton('GetValue', self)
self.btn4.move(btnposx,btnposy+220)
self.btn4.clicked.connect(self.cb_get)
self.cb = QComboBox(self)
self.cb.move(btnposx+120,btnposy+150)
self.cb.resize(80,22)
self.cb.setMaximumSize(QSize(80,1000000))
self.cb.addItem('A')
self.cb.addItem('B')
self.cb.addItem('C')
self.cb.addItem('D')
self.cb.addItem('E')
self.show()
#pyqtSlot()
def cb_get(self):
global s
cbtext = str(self.cb.currentText())
s = cbtext
print(s)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
This code shows a PyQt4 Widget. Function cb_get acquires the Value of a QcomboBox and can be used within the class App(). The Value is saved to variable s. How do I use variable s globally?
The only way I seem to get it to work is to write a new function for s and execute it on button click:
import sys
from PyQt4.QtGui import QApplication, QMainWindow, QPushButton, QLineEdit, QLabel, QComboBox, QProgressBar, QFileDialog
from PyQt4.QtCore import QSize, pyqtSlot
class App(QMainWindow):
def __init__(self):
super(App, self).__init__()
self.setGeometry(500, 300, 820, 350)
self.setWindowTitle("Widget")
self.initUI()
def initUI(self):
#Buttons
btnposx = 30
btnposy = 50
self.btn4 = QPushButton('GetValue', self)
self.btn4.move(btnposx,btnposy+220)
self.btn4.clicked.connect(self.cb_get)
self.btn4.clicked.connect(self.p)
self.cb = QComboBox(self)
self.cb.move(btnposx+120,btnposy+150)
self.cb.resize(80,22)
self.cb.setMaximumSize(QSize(80,1000000))
self.cb.addItem('A')
self.cb.addItem('B')
self.cb.addItem('C')
self.cb.addItem('D')
self.cb.addItem('E')
self.show()
#pyqtSlot()
def cb_get(self):
global s
s = str(self.cb.currentText())
def p(self):
print(s)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
Well, at least now it has ist own function and I can write code for it seperately.
def initUI(self):
#Buttons
btnposx = 30
btnposy = 50
self.btn4 = QPushButton('GetValue', self)
self.btn4.move(btnposx,btnposy+220)
self.btn4.clicked.connect(self.cb_get)
self.cb = QComboBox(self)
self.cb.move(btnposx+120,btnposy+150)
self.cb.resize(80,22)
self.cb.setMaximumSize(QSize(80,1000000))
self.cb.addItem('A')
self.cb.addItem('B')
self.cb.addItem('C')
self.cb.addItem('D')
self.cb.addItem('E')
self.s = None # initialize it here so you don't have to use global
self.show()
#pyqtSlot()
def cb_get(self):
cbtext = str(self.cb.currentText())
self.s = cbtext
def get_s(self):
return self.s
and
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
# print(ex.get_s) # this won't work since you have to click on btn4 first
sys.exit(app.exec_())