Bring to the front the MainWindow in Pyqt5 - python

I am dealing with the following problem, while I am having multiple windows open, i would like to build a function linked to a button to bring to the front the Main window.
Thank you in advance.
import sys
from PyQt5 import QtGui
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QLabel)
class Window2(QMainWindow): # <===
def __init__(self):
super().__init__()
self.setWindowTitle("Window 2")
self.pushButton = QPushButton("Back to window1", self)
self.pushButton.clicked.connect(self.window1)
def window1(self): # <===
pass;
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.title = "First Window"
self.top = 100
self.left = 100
self.width = 680
self.height = 500
self.pushButton = QPushButton("Go to window 2 ", self)
self.pushButton.move(275, 200)
self.label = QLabel("window 1", self)
self.label.move(285, 175)
self.setWindowTitle(self.title)
self.setGeometry(self.top, self.left, self.width, self.height)
self.pushButton.clicked.connect(self.window2) # <===
def window2(self): # <===
self.w = Window2()
self.w.show()
def main():
app = QApplication(sys.argv)
window = Window()
window.show()
#app.exec_()
exit(app.exec_())
if __name__=='__main__':
main()
Regards
I am expecting a function to call back the widget "Window"

You could emit a signal from your second window that your fist window listens for, and calls .raise_() when triggered.
Update: Added a call to activateWindow in the first windows callback. thanks #musicmante
For example:
import sys
from PyQt5 import QtGui
from PyQt5.QtCore import pyqtSignal # import signal
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QLabel)
class Window2(QMainWindow):
unfocus = pyqtSignal() # create signal
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setWindowTitle("Window 2")
self.pushButton = QPushButton("Back to window1", self)
# button press emits signal
self.pushButton.clicked.connect(self.unfocus.emit)
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.title = "First Window"
self.top = 100
self.left = 100
self.width = 680
self.height = 500
self.pushButton = QPushButton("Go to window 2 ", self)
self.pushButton.move(275, 200)
self.label = QLabel("window 1", self)
self.label.move(285, 175)
self.setWindowTitle(self.title)
self.setGeometry(self.top, self.left, self.width, self.height)
self.pushButton.clicked.connect(self.window2) # <===
def window2(self): # <===
self.w = Window2()
self.w.unfocus.connect(self.bring_to_top) # listen for signal and raise_ to top focus
self.w.show()
def bring_to_top(self):
self.activateWindow()
self.raise_()
def main():
app = QApplication(sys.argv)
window = Window()
window.show()
#app.exec_()
exit(app.exec_())
if __name__=='__main__':
main()

Related

PyQt5 custom widget split backghround?

I have had this happening multiple times. When I create a custom widget with an image in it all child widgets get seperated. How do I prevent that?
Full code that has the same outcome:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
class CustomWidget(QWidget):
def __init__(self):
super(CustomWidget, self).__init__()
self.layout = QHBoxLayout()
self.setLayout(self.layout)
self.setStyleSheet(r'QWidget {background-color:#353634;}')
self.name_label = QLabel('name')
self.qty_label = QLabel('999')
self.image_pix = QPixmap(IMAGEPATH)
self.image_pix = self.image_pix.scaled(48, 48)
self.icon = QLabel()
self.icon.setPixmap(self.image_pix)
self.layout.addWidget(self.icon)
self.layout.addWidget(self.name_label)
self.layout.addWidget(self.qty_label)
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.width, self.height = 425,350
self.resize(self.width, self.height)
custom_widget = CustomWidget()
self.setCentralWidget(custom_widget)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
app.exec()
app.quit()

how to call the thread from a different function pyqt5

import sys
from PyQt5 import QtCore
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QMainWindow, QApplication, QPlainTextEdit, QApplication, QMainWindow, QLabel, QComboBox
from PyQt5.QtGui import QPixmap
from pynput import keyboard
from pynput.keyboard import Listener, Controller
import pyperclip as pc
keyboard = Controller()
class App(QMainWindow):
def __init__(self, parent=None):
super(App, self).__init__(parent)
#super().__init__()
label = QLabel(self)
pixmap = QPixmap('E:/copycat/new.png')
label.setPixmap(pixmap)
label.setGeometry(0,0,900,400)
self.title = 'COPYCAT'
self.left = 10
self.top = 10
self.width = 400
self.height = 140
self.initUI()
self.key()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
###########
combo = QComboBox(self)
shotcut_list = ["Key.f9","Key.f2","Key.f3","Key.f4","Key.f5","Key.f6","Key.f7","Key.f8","Key.f1","Key.f10","Key.f11","Key.f12"]
combo.addItems(shotcut_list)
global shortcut
global cptext
shortcut = combo.currentText()
combo.setGeometry(350, 120, 120, 30)
combo.activated[str].connect(self.onChanged)
# Create textbox
self.textbox = QPlainTextEdit(self)
self.textbox.move(20, 160)
self.textbox.setReadOnly(True)
self.textbox.resize(500,205)
self.setGeometry(70,70,540,388)
self.show()
def onChanged(self, text):
global shortcut
shortcut=text
def print_key(self,key):
if str(key) == shortcut:
cptext = pc.paste()
keyboard.type(cptext)
self.textbox.insertPlainText(cptext)
self.textbox.insertPlainText("\n")
def key(self):
listener = Listener(on_press=self.print_key)
listener.start()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ex = App()
#ex.key()
sys.exit(app.exec_())
The above code shows an error when I update the textbox from the print_key function
It shows this error:
Cannot queue arguments of type 'QTextBlock'
(Make sure 'QTextBlock' is registered using qRegisterMetaType()
Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType()
The callback associated with on_press is executed in a secondary thread so your implementation is updating the GUI from a secondary thread which Qt prohibits, instead you should use the signals as they are thread-safe.
import sys
import threading
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import (
QApplication,
QComboBox,
QLabel,
QMainWindow,
QPlainTextEdit,
)
from pynput.keyboard import Listener, Controller
import pyperclip as pc
class KeyboardListener(QObject):
textChanged = pyqtSignal(str)
def __init__(self, shortcut, parent=None):
super().__init__(parent)
self._shortcut = shortcut
listener = Listener(on_press=self.handle_pressed)
listener.start()
self.mutex = threading.Lock()
#property
def shortcut(self):
return self._shortcut
def handle_pressed(self, key):
with self.mutex:
if str(key) == self.shortcut:
cptext = pc.paste()
self.textChanged.emit(cptext)
#pyqtSlot(str)
def update_shortcut(self, shortcut):
with self.mutex:
self._shortcut = shortcut
class App(QMainWindow):
def __init__(self, parent=None):
super(App, self).__init__(parent)
# super().__init__()
label = QLabel(self)
pixmap = QPixmap("E:/copycat/new.png")
label.setPixmap(pixmap)
label.setGeometry(0, 0, 900, 400)
self.title = "COPYCAT"
self.left = 10
self.top = 10
self.width = 400
self.height = 140
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
###########
combo = QComboBox(self)
shotcut_list = [
"Key.f9",
"Key.f2",
"Key.f3",
"Key.f4",
"Key.f5",
"Key.f6",
"Key.f7",
"Key.f8",
"Key.f1",
"Key.f10",
"Key.f11",
"Key.f12",
]
combo.addItems(shotcut_list)
shortcut = combo.currentText()
combo.setGeometry(350, 120, 120, 30)
self.textbox = QPlainTextEdit(self)
self.textbox.move(20, 160)
self.textbox.setReadOnly(True)
self.textbox.resize(500, 205)
self.setGeometry(70, 70, 540, 388)
self.keyboard = Controller()
self.listener = KeyboardListener(combo.currentText())
combo.activated[str].connect(self.listener.update_shortcut)
self.listener.textChanged.connect(self.handle_text_changed)
#pyqtSlot(str)
def handle_text_changed(self, text):
self.textbox.insertPlainText(text)
self.textbox.insertPlainText("\n")
self.keyboard.type(text)
def main():
app = QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()

PyQt5 Switch between window after time in a loop

i use the code below, found on stackoverflow. i want to build a loop which getting started with a button on the main window. After clicked window2 should open for 30 seconds. then window3 should open for 30 seconds. then window2 should open and so on.
i make a slide methode but it wont work.
i try it with the window2() and window3() and slide() methode
what is my target?
i want a slideshow with the two window(window2 & window3) that alternate.
not more but it is an endless loop
import sys
from PyQt5 import QtGui
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QToolTip, QMessageBox, QLabel)
class Window2(QMainWindow): # <===
def __init__(self):
super().__init__()
self.setWindowTitle("Window22222")
class Window3(QMainWindow): # <===
def __init__(self):
super().__init__()
self.setWindowTitle("Window333333")
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.title = "First Window"
self.top = 100
self.left = 100
self.width = 680
self.height = 500
self.pushButton = QPushButton("Start", self)
self.pushButton.move(275, 200)
self.pushButton.setToolTip("<h3>Start the Session</h3>")
self.pushButton.clicked.connect(self.window2)
self.pushButton1 = QPushButton("Start", self)
self.pushButton1.move(20, 20)
self.pushButton1.setToolTip("<h3>Start the Session</h3>")
self.pushButton1.clicked.connect(self.slide)
self.main_window()
def main_window(self):
self.label = QLabel("Manager", self)
self.label.move(285, 175)
self.setWindowTitle(self.title)
self.setGeometry(self.top, self.left, self.width, self.height)
self.show()
def window2(self): # <===
self.w2 = Window2()
self.w2.show()
time.sleep(5)
self.w3 = Window3()
self.w3.show()
self.w2.hide()
self.window3()
#self.hide()
def window3(self): # <===
self.w3 = Window3()
self.w3.show()
time.sleep(5)
self.w2 = Window2()
self.w2.show()
self.w3.hide()
self.window2()
#self.hide()
def slide(self):
print ("slide")
self.window2()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
sys.exit(app.exec())
Try it:
import sys
#import time
from PyQt5 import QtGui, QtCore
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QToolTip, QMessageBox, QLabel)
class Window2(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Window 22222")
class Window3(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Window 333333")
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.title = "First Window"
self.top, self.left, self.width, self.height = 100, 100, 680, 500
self.flag = ...
self.pushButton = QPushButton("Start", self)
self.pushButton.move(275, 200)
self.pushButton.setToolTip("<h3>Start the Session</h3>")
self.pushButton.clicked.connect(lambda: self.start_slide(True)) #(self.window2)
self.pushButton1 = QPushButton("Start", self)
self.pushButton1.move(20, 20)
self.pushButton1.setToolTip("<h3>Start the Session</h3>")
self.pushButton1.clicked.connect(lambda: self.start_slide(False))
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
self.main_window()
self.w2 = Window2()
self.w3 = Window3()
self.timer = QtCore.QTimer(self)
self.timer.timeout.connect(self.viewWindows)
def start_slide(self, flag):
self.timer.stop()
self.w3.hide()
self.w2.hide()
if flag: self.w2.show()
else: self.w3.show()
self.flag = not flag
self.timer.start(5000)
def viewWindows(self):
if self.flag:
self.w2.show()
self.w3.hide()
else:
self.w3.show()
self.w2.hide()
self.flag = not self.flag
def closeEvent(self, event):
self.w2.close()
self.w3.close()
self.close()
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
def main_window(self):
self.label = QLabel("Manager", self)
self.label.move(285, 175)
self.setWindowTitle(self.title)
self.setGeometry(self.top, self.left, self.width, self.height)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())

Python using QGridLayout not add widget

I'm new to Qt5, I have a simple QGridLayout layout mask .
I want to create a windows with the widget resize with resize of window
this is the code
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog ,QVBoxLayout,QGroupBox,QGridLayout
class MainWindow(QtWidgets.QMainWindow, QtWidgets.QFileDialog, QtWidgets.QLineEdit):
def __init__(self):
super().__init__()
self.title = "Calcolo Hash"
self.top = 100
self.left = 100
self.width = 800
self.height = 330
self.InitWindow()
def InitWindow(self):
self.setWindowIcon(QtGui.QIcon("icona_aprie.png"))
self.setWindowTitle(self.title)
self.setGeometry(self.top, self.left, self.width, self.height)
self.creamaschera()
self.show()
def creamaschera(self):
print ("creazione maschera")
layout = QtWidgets.QGridLayout()
self.txtcartella = QtWidgets.QLineEdit()
self.lblprova = QtWidgets.QLabel("Please enter new name:")
# self.txtcartella.setGeometry(QtCore.QRect(10, 10, 301, 20))
# self.txtcartella.setObjectName("txtcartella")
layout.addWidget(self.lblprova,0,0)
layout.addWidget(self.txtcartella,0,1)
self.setLayout(layout)
# self.horizontalGroupBox.setLayout(layout)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
#w.show()
sys.exit(app.exec_())
but when I run the mask is empy.
I make the base with Qt5 designer and convert it to python. I want to refactor the class in a best workout.
Where is the error?
You should setLayout in a widget rather than setting it to the MainWindow since you are using the MainWindow class itself and while accessing the methods and properties of the class MainWindow you can be more specific
import sys
from PyQt5 import QtCore, QtGui
from PyQt5.QtWidgets import (QLineEdit, QMainWindow, QWidget,
QGridLayout, QLabel, QApplication)
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.title = "Calcolo Hash"
self.top = 100
self.left = 100
self.width = 800
self.height = 330
self.InitWindow()
def InitWindow(self):
self.setWindowIcon(QtGui.QIcon("icona_aprie.png"))
self.setWindowTitle(self.title)
self.setGeometry(self.top, self.left, self.width, self.height)
self.creamaschera()
def creamaschera(self):
print("creazione maschera")
Layout = QGridLayout()
self.txtcartella = QLineEdit()
self.lblprova = QLabel("Enter Your Name")
self.lblprova.setGeometry(QtCore.QRect(15, 15, 301, 20))
self.txtcartella.setObjectName("txtcartella")
Layout.addWidget(self.lblprova, 0, 0)
Layout.addWidget(self.txtcartella, 0, 1)
# Widget to setLayout in it since you are using MainWindow as an Class
widget = QWidget()
widget.setLayout(Layout)
# SetCentralWidget without this widget won't be placed
self.setCentralWidget(widget)
# self.horizontalGroupBox.setLayout(layout)
if __name__ == "__main__":
app = QApplication(sys.argv)
MainWindow = MainWindow()
MainWindow.show()
sys.exit(app.exec_())

change label from other class in a different file

I am creating an application where I have a main window whit a label and then a docked widget that is in another file. I want to change the main windows label from a button at the docked widget. I try to import the main window file but then I can not access to the label. And I also tried to call a function in the main windows that changes the label but then the label does not change.
Here is the code:
main_window.py:
import results_window
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.define_main_windows()
self.create_dock_widgets()
def define_main_windows(self):
# Define de Main window properties
self.setMinimumSize(QSize(300, 100))
self.setWindowTitle("Python SkyLibris")
self.setWindowIcon(QtGui.QIcon("skylibris_icon.png"))
self.setStyleSheet("QMainWindow {background: 'white';}")
self.top = 50
self.left = 0
self.width = 1300
self.height = 400
self.setGeometry(self.left, self.top, self.width, self.height)
self.result = QLabel("result:")
self.setCentralWidget(self.result)
def create_dock_widgets(self):
# Create dock widgets
self.results_window = results_window.results_window()
self.resultsWindowDock = QDockWidget("Results Viewer", self)
self.resultsWindowDock.setWidget(self.results_window )
self.resultsWindowDock.setFloating(False)
self.resultsWindowDock.setVisible(True)
self.addDockWidget(Qt.LeftDockWidgetArea, self.resultsWindowDock)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
app.setStyle('Fusion')
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())
results_window.py:
import main_window
class results_window(QWidget):
def __init__(self):
super(results_window, self).__init__()
print("init")
self.label = QLabel()
self.value = QLineEdit()
self.bt = QPushButton("Click")
self.bt.clicked.connect(self.clickMethod)
self.main_layout = QVBoxLayout()
self.main_layout.addWidget(self.label)
self.main_layout.addWidget(self.value)
self.main_layout.addWidget(self.bt)
self.setLayout(self.main_layout)
def clickMethod(self):
print(self.value.text())
text = self.value.text()
main_window.result.setText(text)
You are using the wrong tools, for example your code has a circular import that causes your application to close since it is equivalent to a while True.
In Qt, signals and slots are used to share data asynchronously, as well as contributing to the fact that there is no coupling between classes. In your case, Results_Window must have a signal that transmits that information to the MainWindow, this signal must be emit within clickMethod.
results_window.py
from PyQt5 import QtCore, QtWidgets
class Results_Window(QtWidgets.QWidget):
resultChanged = QtCore.pyqtSignal(str)
def __init__(self):
super(Results_Window, self).__init__()
print("init")
self.label = QtWidgets.QLabel()
self.value = QtWidgets.QLineEdit()
self.bt = QtWidgets.QPushButton("Click")
self.bt.clicked.connect(self.clickMethod)
main_layout = QtWidgets.QVBoxLayout(self)
main_layout.addWidget(self.label)
main_layout.addWidget(self.value)
main_layout.addWidget(self.bt)
#QtCore.pyqtSlot()
def clickMethod(self):
text = self.value.text()
self.resultChanged.emit(text)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
app.setStyle('Fusion')
w = Results_Window()
w.show()
sys.exit(app.exec_())
main_window.py
from PyQt5 import QtCore, QtGui, QtWidgets
import results_window
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.define_main_windows()
self.create_dock_widgets()
def define_main_windows(self):
self.setMinimumSize(QtCore.QSize(300, 100))
self.setWindowTitle("Python SkyLibris")
self.setWindowIcon(QtGui.QIcon("skylibris_icon.png"))
self.setStyleSheet("QMainWindow {background: 'white';}")
top, left, width, height = 50, 0, 1300, 400
self.setGeometry(left, top, width, height)
self.result = QtWidgets.QLabel("result:")
self.setCentralWidget(self.result)
def create_dock_widgets(self):
self.results_window = results_window.Results_Window()
self.results_window.resultChanged.connect(self.result.setText)
self.resultsWindowDock = QtWidgets.QDockWidget("Results Viewer", self)
self.resultsWindowDock.setWidget(self.results_window )
self.resultsWindowDock.setFloating(False)
self.resultsWindowDock.setVisible(True)
self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.resultsWindowDock)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
app.setStyle('Fusion')
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())
I had similar problem in PyQT5 where I was unable to access and set the local variables. After a lot of struggle I found writing to file and reading from file as the best solution. Simply write the desired output to file and access the same info from other file. Works great!

Categories