QPushButton does not work
-
Hello everyone,
I have been working on an application and I have designed the interface using Qt Designer. I'm using a Qstackedwidget to have multiple pages (each page is a separate widget). When I move to another widget, qpushbutton does not work. If I run that widget by itself, buttons do work but when I run the application I cannot run the segment which is supposed to run after button is pressed. Do you have any idea why something like this would happen?
Thanks in advance
-
The only idea we can have is that it is programmed incorrectly. Unless we can see your actual code, or a minimal example that displays the problem, and some basic information about the environment it runs in then there is not much that can be done to help.
-
Hey Chris!
Thanks for replying back. This is the code for the menu which changes to other widgets. I have two buttons on the menu page which when I click on them, I'm able to move to the widget. But none of the buttons work. If you need anything else, please tell me.
import os import sys from PyQt5 import uic from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QStackedWidget, QApplication from PyQt5 import QtGui class MainWindow(QStackedWidget): def __init__(self): super().__init__() uic.loadUi(os.path.join('ui_files', 'ciri.ui'), self) self.setWindowIcon(QtGui.QIcon(os.path.join('images', 'rabbit.png'))) self.open = None self.setCurrentIndex(0) self.setAttribute(Qt.WA_TranslucentBackground) self.show() self.revealButton.clicked.connect(lambda: self.setCurrentWidget(self.extractPage)) self.hideButton.clicked.connect(lambda: self.setCurrentWidget(self.embedPage)) if __name__ == '__main__': app = QApplication(sys.argv) app.setApplicationName('Ciri') window = MainWindow() window.show() sys.exit(app.exec())
-
@botqe
There is nothing here to show where these buttons are. I guess since your whole main window is aQStackedWidget
you have one button on each page? "I have two buttons on the menu page" --- what is a "menu page"? Show the content of the.ui
file. " I cannot run the segment which is supposed to run after button is pressed." --- what is a "segment" that is supposed to run after a button is pressed? -
@JonB That was the code for the following page (menu page):
When I click on "Hide" or "Reveal", it works fine and I move to the next page of stacked widget which is the following:
When I click on select file, it does not run the code segment which is supposed to open file manager (But if I run the separate file for the next page by itself, button works). I tried copying ui file but its too long and because of length limitation, it does not allow me to copy it.
I have copied a piece of code to understand what open file code segment looks like:
class Embed(QStackedWidget): def __init__(self): super(Embed, self).__init__() uic.loadUi(os.path.join('ui_files', 'ciri.ui'), self) self.setWindowIcon(QtGui.QIcon(os.path.join('images', 'rabbit.png'))) self.setCurrentIndex(2) self.show() self.selected_carrier = None self.saved = None self.open = None self.input_file = None self.b_pass = None self.selectFileButton.clicked.connect(self.open_file) self.selectCarrierButton.clicked.connect(self.open_carrier) self.encryptButton.clicked.connect(self.set_password) self.embedButton.clicked.connect(self.embed_it) def open_file(self): try: selected_file = QFileDialog.getOpenFileName(self, 'Open File', '', 'Text Files (*.txt)') with open(selected_file[0], 'rb') as inf: self.input_file = inf.read() except Exception as e: print(e)
-
Ok, I am going to assume that the second page of the MainWindow stacked widget is an instance of the Embed class. The embed class is also a QStackedWidget. Did you intend to have nested QStackedWidgets (that would be an odd arrangement) ?
In general, QWidget::show() would not normally be called in the constructor of the widget. This should definitely be removed from both class constructors. For pages in a stacked widget, visibility or otherwise is determined exclusively by the containing QStackedWidget. For the main application window(s) the QWidget::show() would typical be in the main() (as it is in your Python).
Both MainWindow and Embed classes load the same UI file, yet your screen shots are different. Bit confusing.
This is what I think your program could look like:
### main.py import os import sys from PyQt5.QtWidgets import QApplication from mainwindow import MainWindow if __name__ == '__main__': app = QApplication(sys.argv) app.setApplicationName('Ciri') window = MainWindow() window.show() sys.exit(app.exec()) ### mainwindow.py import os import sys from PyQt5 import uic from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QStackedWidget, QApplication from PyQt5 import QtGui class MainWindow(QStackedWidget): def __init__(self): super(MainWindow, self).__init__() ui = uic.loadUi('mainwindow.ui', self) self.setCurrentIndex(0) self.menuPage.revealButton.clicked.connect(lambda: self.setCurrentWidget(self.extractPage)) self.menuPage.hideButton.clicked.connect(lambda: self.setCurrentWidget(self.embedPage)) ### menu.py from PyQt5 import uic from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QWidget from PyQt5 import QtGui class Menu(QWidget): def __init__(self): super(Menu, self).__init__() uic.loadUi('menu.ui', self) ### extract.py from PyQt5 import uic from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QWidget from PyQt5 import QtGui class Extract(QWidget): def __init__(self): super(Extract, self).__init__() uic.loadUi('extract.ui', self) ### embed.py from PyQt5 import uic from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QWidget, QFileDialog from PyQt5 import QtGui class Embed(QWidget): def __init__(self): super(Embed, self).__init__() uic.loadUi('embed.ui', self) self.selected_carrier = None self.saved = None self.open = None self.input_file = None self.b_pass = None self.selectFileButton.clicked.connect(self.open_file) #self.selectCarrierButton.clicked.connect(self.open_carrier) #self.encryptButton.clicked.connect(self.set_password) #self.embedButton.clicked.connect(self.embed_it) def open_file(self): try: selected_file = QFileDialog.getOpenFileName(self, 'Open File', '', 'Text Files (*.txt)') with open(selected_file[0], 'rb') as inf: self.input_file = inf.read() except Exception as e: print(e) ### mainwindow.ui <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>stackedWidget</class> <widget class="QStackedWidget" name="stackedWidget"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>503</width> <height>419</height> </rect> </property> <property name="windowTitle"> <string>StackedWidget</string> </property> <widget class="Menu" name="menuPage"/> <widget class="Extract" name="extractPage"/> <widget class="Embed" name="embedPage"/> </widget> <customwidgets> <customwidget> <class>Embed</class> <extends>QWidget</extends> <header>embed.h</header> <container>1</container> </customwidget> <customwidget> <class>Extract</class> <extends>QWidget</extends> <header>extract.h</header> <container>1</container> </customwidget> <customwidget> <class>Menu</class> <extends>QWidget</extends> <header>menu.h</header> <container>1</container> </customwidget> </customwidgets> <resources/> <connections/> </ui> ### menu.ui <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Form</class> <widget class="QWidget" name="Form"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>400</width> <height>300</height> </rect> </property> <property name="windowTitle"> <string>Form</string> </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> <widget class="QPushButton" name="hideButton"> <property name="text"> <string>Hide</string> </property> </widget> </item> <item> <widget class="QPushButton" name="revealButton"> <property name="text"> <string>Reveal</string> </property> </widget> </item> </layout> </widget> <resources/> <connections/> </ui> ### extract.ui <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Form</class> <widget class="QWidget" name="Form"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>400</width> <height>300</height> </rect> </property> <property name="windowTitle"> <string>Form</string> </property> </widget> <resources/> <connections/> </ui> ### embed.ui <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Form</class> <widget class="QWidget" name="Form"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>400</width> <height>300</height> </rect> </property> <property name="windowTitle"> <string>Form</string> </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> <widget class="QPushButton" name="selectFileButton"> <property name="text"> <string>Select File</string> </property> </widget> </item> <item> <widget class="QPushButton" name="selectCarrierButton"> <property name="text"> <string>Select Carrier</string> </property> </widget> </item> <item> <widget class="QPushButton" name="encryptButton"> <property name="text"> <string>Set Password</string> </property> </widget> </item> <item> <widget class="QPushButton" name="embedButton"> <property name="text"> <string>Embed</string> </property> </widget> </item> </layout> </widget> <resources/> <connections/> </ui>
-
@ChrisW67 To be honest, the previous version of the application had different .ui files for each page and it worked fine. But I decided to have one .ui file (stackedwidget) and change between pages. This is why the code seems a bit confusing. So instead of having multiple ui files for each separate python file, I combined them into one using Qt Designer and Qstackedwidget. Right now, if I decided to change back to multiple ui files (one for each page), qpushbutton works well but in this code, it doesn't. If it was a problem of loading ui file, the graphics would not load. I'm able to move between pages as well, but when I move to another page, clicking on qpushbutton does not work...
-
@botqe So what you have is more like this?
### main.py import os import sys from PyQt5.QtWidgets import QApplication from mainwindow import MainWindow if __name__ == '__main__': app = QApplication(sys.argv) app.setApplicationName('Ciri') window = MainWindow() window.show() sys.exit(app.exec()) ### mainwindow.py import os import sys from PyQt5 import uic from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QApplication, QStackedWidget, QFileDialog from PyQt5 import QtGui class MainWindow(QStackedWidget): def __init__(self): super(MainWindow, self).__init__() ui = uic.loadUi('mainwindow.ui', self) self.selected_carrier = None self.saved = None self.open = None self.input_file = None self.b_pass = None self.setCurrentIndex(0) # Menu Page self.revealButton.clicked.connect(lambda: self.setCurrentWidget(self.extractPage)) self.hideButton.clicked.connect(lambda: self.setCurrentWidget(self.embedPage)) # Embed Page self.selectFileButton.clicked.connect(self.open_file) self.selectCarrierButton.clicked.connect(self.open_carrier) self.encryptButton.clicked.connect(self.set_password) self.embedButton.clicked.connect(self.embed_it) def open_file(self): try: selected_file = QFileDialog.getOpenFileName(self, 'Open File', '', 'Text Files (*.txt)') with open(selected_file[0], 'rb') as inf: self.input_file = inf.read() except Exception as e: print(e) def open_carrier(self): print("open_carrier") def set_password(self): print("set_password") def embed_it(self): print("embed_it") ### mainwindouw.ui <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>stackedWidget</class> <widget class="QStackedWidget" name="stackedWidget"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>503</width> <height>419</height> </rect> </property> <property name="windowTitle"> <string>Ciri</string> </property> <property name="currentIndex"> <number>2</number> </property> <widget class="QWidget" name="menuPage"> <layout class="QVBoxLayout" name="verticalLayout"> <item> <widget class="QPushButton" name="hideButton"> <property name="text"> <string>Hide</string> </property> </widget> </item> <item> <widget class="QPushButton" name="revealButton"> <property name="text"> <string>Reveal</string> </property> </widget> </item> </layout> </widget> <widget class="QWidget" name="extractPage"> <layout class="QVBoxLayout" name="verticalLayout_3"> <item> <widget class="QLabel" name="label"> <property name="text"> <string>Empty</string> </property> </widget> </item> </layout> </widget> <widget class="QWidget" name="embedPage"> <layout class="QVBoxLayout" name="verticalLayout_2"> <item> <widget class="QPushButton" name="selectFileButton"> <property name="text"> <string>Select File</string> </property> </widget> </item> <item> <widget class="QPushButton" name="selectCarrierButton"> <property name="text"> <string>Select Carrier</string> </property> </widget> </item> <item> <widget class="QPushButton" name="encryptButton"> <property name="text"> <string>Set Password</string> </property> </widget> </item> <item> <widget class="QPushButton" name="embedButton"> <property name="text"> <string>Embed</string> </property> </widget> </item> </layout> </widget> </widget> <resources/> <connections/> </ui>
This works, right?
-
@ChrisW67 This is my code for menu page (1st image: eyes) from which I move to other pages:
class MainWindow(QStackedWidget): def __init__(self): super().__init__() uic.loadUi(os.path.join('ui_files', 'ciri.ui'), self) self.setWindowIcon(QtGui.QIcon(os.path.join('images', 'rabbit_small.png'))) self.open = None self.setCurrentIndex(0) self.setAttribute(Qt.WA_TranslucentBackground) self.show() self.revealButton.clicked.connect(lambda: self.setCurrentWidget(self.extractPage)) self.hideButton.clicked.connect(lambda: self.setCurrentWidget(self.embedPage)) if __name__ == '__main__': app = QApplication(sys.argv) app.setApplicationName('Ciri') window = MainWindow() window.show() sys.exit(app.exec())
This works well. Buttons and everything. But when I click on button to change widget and move to other ones, buttons on other pages do not work.
-
If ciri.ui is the entire UI with all the widgets composed into a QStackedWidget then all the QPushButton instances exist in the MainWindow object scope (as in my example). The code you just posted connects only the Reveal and Hide buttons, so I do not know how you expect the other buttons to do anything.
Does my three file example work for you or not?
-
@ChrisW67 I just tested your code and it works!
So should I just put all of the connecting actions in this file or is there anyway to put them in separate python files? I wanted to make the code cleaner by removing dividing a single python file into multiple modules.
-
If you want to separate functionality into multiple Python file then my first example is approximately the direction to go. The EmbedPage has code related to its own buttons and MainWindow does not know about this. The first example does break the encapsulation of the MenuPage in order to do the connect() plumbing with the reveal/hide buttons. You could tidy that up by having MenuPage emit a signal corresponding to a desired page, and then connect that to setCurrentPage() in the MainWindow.
If not, then my second example.
-
@botqe said in QPushButton does not work:
To be honest, the previous version of the application had different .ui files for each page and it worked fine. But I decided to have one .ui file (stackedwidget) and change between pages.
FWIW, when I used Designer and had multiple pages to go into a
QStackedWidget
I designed the pages separately within their own.ui
s and then just put them into the (blank) stacked widget dynamically at runtime start up.