Basic Widget Interaction with PyQt - python

Please can someone tell me what im doing wrong here with respect to calling pwTxt.text.
#!/usr/bin/python
import sys
from PyQt4 import QtCore, QtGui
from mainwindow import Ui_MainWindow
class MyForm(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
def on_pwExtract_pressed(self):
print self.pwTxt.text
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = MyForm()
myapp.show()
sys.exit(app.exec_())
The line print self.pwTxt.text fails because it can't find the widget, pwTxt is a QLineEdit defined on the main window. I just made it in QTDesigner and generated python code with pyuic4.
How do I correctly reference other widgets on the same window, in this case I just want to get the text from a QLineEdit named pwTxt when the QPushButton pwExtract is pressed.
Thanks a lot.

Try:
print self.ui.pwTxt.text()

Related

PyQt4 How keep a QWidget always on top?

I'm using PyQt4 with python 2.7 on Windows7
I have a QWidget that I want to stay above the QMainWindow while clicking on the main. The idea is that the main will contain a series of 'edit' buttons that will open the edit widget, while the edit widget refreshes with info contained on the main. I don't particularly care if either is "always on top" as long as the widget stays in front of the main window.
There are a couple of questions that address this topic, but I'm not seeing an answer that works for my specific use case. One deals in widgets but provides an answer only for the app main window (widget stays above other environmental windows but falls behind the application main window when clicking on the main), and the other addresses Qt generally but not a pythonic example:
PyQt: Always on top
How keep a QWidget always on top?
Here is the code I have so far:
from PyQt4 import QtCore, QtGui
class Ui_MainWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self, None, QtCore.Qt.WindowStaysOnTopHint)
self.setWindowTitle("MainWindow")
self.resize(400, 300)
class Ui_Widget(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self, None, QtCore.Qt.WindowStaysOnTopHint)
self.setWindowTitle("Widget")
self.resize(400, 300)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = Ui_MainWindow()
MainWindow.show()
Widget = Ui_Widget()
Widget.show()
sys.exit(app.exec_())
If you want Ui_Widget to always be on top of Ui_MainWindow, Ui_Widget must be a child of Ui_MainWindow and the flag Qt::Dialog must be activated as shown below:
from PyQt4 import QtCore, QtGui
class Ui_MainWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.setWindowTitle("MainWindow")
self.resize(400, 300)
class Ui_Widget(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setWindowFlags(self.windowFlags() | QtCore.Qt.Dialog)
self.setWindowTitle("Widget")
self.resize(400, 300)
self.move(200, 150)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = Ui_MainWindow()
MainWindow.show()
Widget = Ui_Widget(MainWindow)
Widget.show()
sys.exit(app.exec_())

How to show the stackwidget?

I'm trying to use the stackWidget to show different widgets .
However when I pressed the item on the listWdget , stackWidget below will not be displayed.
Here is my code,and I don't know where is wrong.
#!/usr/bin/python
# music_1.py
import sys
from PyQt4 import QtGui, QtCore
from music_ui import Ui_Form
class music(QtGui.QDialog):
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
self.ui.listWidget.insertItem(0,("Warm"))
self.ui.listWidget.insertItem(1,("Funny"))
self.ui.listWidget.insertItem(2,("Terror"))
self.ui.stackedWidget=QtGui.QStackedWidget()
warm=Warm()
funny=Funny()
terror=Terror()
self.ui.stackedWidget.addWidget(warm)
self.ui.stackedWidget.addWidget(funny)
self.ui.stackedWidget.addWidget(terror)
self.connect(self.ui.listWidget,QtCore.SIGNAL("currentRowChanged(int)"),self.ui.stackedWidget,QtCore.SLOT("setCurrentIndex(int)"))
class Warm(QtGui.QWidget):
def __init__(self,parent=None):
super(Warm,self).__init__(parent)
w1=QtGui.QPushButton("w1")
w2=QtGui.QPushButton("w2")
buttonLayout=QtGui.QHBoxLayout()
buttonLayout.addStretch(1)
buttonLayout.addWidget(w1)
buttonLayout.addWidget(w2)
class Funny(QtGui.QWidget):
def __init__(self,parent=None):
super(Funny,self).__init__(parent)
f1=QtGui.QPushButton("f1")
f2=QtGui.QPushButton("f2")
f3=QtGui.QPushButton("f3")
buttonLayout=QtGui.QHBoxLayout()
buttonLayout.addStretch(1)
buttonLayout.addWidget(f1)
buttonLayout.addWidget(f2)
buttonLayout.addWidget(f3)
class Terror(QtGui.QWidget):
def __init__(self,parent=None):
super(Terror,self).__init__(parent)
t1=QtGui.QPushButton("t1")
t2=QtGui.QPushButton("t2")
buttonLayout=QtGui.QHBoxLayout()
buttonLayout.addStretch(1)
buttonLayout.addWidget(t1)
buttonLayout.addWidget(t2)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = music()
myapp.show()
sys.exit(app.exec_())
I never worked with UI Files but this is my guess:
self.ui.stackedWidget=QtGui.QStackedWidget()
here you create a QStackedWidget which gets assigned to the class. The problem is that it is not added to the UI that is getting displayed but just to the instance of the Ui_Form. What you have to do is either:
Add the QStackedWidget in the UI Designer and erase the line above
or
Add the QStackedWidget to one of your layouts
which can be done like this:
self.ui.mySuperCoolLayout.addWidget(self.ui.stackedWidget)

Ui_MainWindow has no attribute 'show'

I'm writing a program which will have multiple windows. I have a main program (attached) that calls the Ui files (that have been converted into .py). The main window and customise window open correctly (the first two listed) but neither the third or fourth windows open correctly, giving me the error
'Ui_MainWindow' object has no attribute 'show'
The main program;
from PyQt4 import QtCore, QtGui
import sys
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mainwin = main_menu_ui.Ui_MainWindow()
mainwin.show()
sys.exit(app.exec_())
def openCustomise(self):
customiseOpen = question_set_menu_ui.Ui_MainWindow()
customiseOpen.show()
sys.exit(app.exec_())
def openQuiz(self):
quizOpen = quiz_window_ui.Ui_MainWindow()
quizOpen.show()
sys.exit(app.exec_())
def addNewSet(self):
addNewOpen = question_set_edit_ui.Ui_MainWindow()
addNewOpen.show()
sys.exit(app.exec_())
Sorry if I'm missing something obvious, I'm learning Qt/Python for college.
The auto-generated UI class that you are importing extends object and doesn't have a show method (open up the .py file for yourself and verify this).
In general, you should structure your GUIs like this:
from PyQt4 import QtCore, QtGui
import sys
from layout_file import main_menu_ui
class MyForm(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = main_menu_ui()
self.ui.setupUi(self)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mainwin = MyForm()
mainwin.show()
sys.exit(app.exec_())
You import your UI from your autogenerated UI file. You have a class that contains your GUI logic. It then sets up your UI layout from your imported UI in its __init__() method.

Open a GUI file from another file PyQT

I've created many GUI interfaces in PyQT using QT Designer, but now I'm trying to open an interface from another one, and I don't know how to do it..
Start.py is the file which run the GUI Interface Authentification_1 and Acceuil_start.py is the file which run the GUI interface Acceuil_2.py, now I want from Start.py to lunch Acceuil_start.py.
Do you have any idea about that ? Thank you.
Here's my code :
Start.py :
import sys
from PyQt4 import QtCore, QtGui
from Authentification_1 import Ui_Fenetre_auth
from Acceuil_2 import Ui_MainWindow #??? Acceuil_2.py is the file which I want to open
class StartQT4(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_Fenetre_auth()
self.ui.setupUi(self)
def authentifier(val): #Slot method
self.Acceuil = Acceuil() #???
self.Acceuil.show() #???
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = StartQT4()
myapp.show()
sys.exit(app.exec_())
Acceuil_start.py
import sys
from PyQt4 import QtCore, QtGui
from Authentification_1 import Ui_Fenetre_auth
from Acceuil_2 import Ui_MainWindow
class StartQT4(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = StartQT4()
myapp.show()
sys.exit(app.exec_())
First, you should to name your GUI classes so they have a different name, and not the generic one, so you could distinct them.
Why you would need to do that? Well - simply, because it makes sense - if every class is representing different type of dialog, so it is the different type - and it should be named differently. Some of the names are/may be: QMessageBox, AboutBox, AddUserDialog, and so on.
In Acceuil_start.py (you should rename class in other module, too).
import sys
from PyQt4 import QtCore, QtGui
from Authentification_1 import Ui_Fenetre_auth
from Acceuil_2 import Ui_MainWindow
class Acceuil(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = Acceuil()
myapp.show()
sys.exit(app.exec_())
in the parent class, when you want to create the window, you are close (but it should work in any case):
def authentifier(val): #Slot method
self.Acceuil = Acceuil(self) # You should always pass the parent to the child control
self.Acceuil.show() #???
About parent issue: If your widget/window is creating another widget, setting creator object to be parent is always a good idea (apart from some singular cases), and you should read this to see why is that so:
QObjects organize themselves in object trees. When you create a QObject with another object as parent, it's added to the parent's children() list, and is deleted when the parent is. It turns out that this approach fits the needs of GUI objects very well. For example, a QShortcut (keyboard shortcut) is a child of the relevant window, so when the user closes that window, the shorcut is deleted too.
Edit - Minimal Working Sample
To see what I am trying to tell you, I've built a simple example. You have two classes - MainWindow and
ChildWindow. Every class can work without other class by creating separate QApplication objects. But, if you import ChildWindow in MainWindow, you will create ChildWindow in slot connected to singleshot timer which will trigger in 5 seconds.
MainWindow.py:
import sys
from PyQt4 import QtCore, QtGui
from ChildWindow import ChildWindow
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
QtCore.QTimer.singleShot(5000, self.showChildWindow)
def showChildWindow(self):
self.child_win = ChildWindow(self)
self.child_win.show()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = MainWindow()
myapp.show()
sys.exit(app.exec_())
ChildWindow.py:
import sys
from PyQt4 import QtCore, QtGui
class ChildWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setWindowTitle("Child Window!")
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = ChildWindow()
myapp.show()
sys.exit(app.exec_())
To reference the other dialog from Start.py, you must prefix it by the module name, which in this case is Acceuil_start. As such, it is OK if there are duplicated function names in each module. So, you would have:
def authentifier(val): #Slot method
dlg = Acceuil_start.StartQT4()
dlg.exec_()
However, if you want these to run from the same process, keep in mind that you can't have two app objects. You would probably want to structure Acceuil_start.py to act like a dialog, rather than a main window. If these are two distinct main windows, you might find it easier to just invoke another Python interpreter with the Acceuil_start.py as a parameter.

how to imitate a link click in QTextBrowser

Actualy, i have different tabs.
what I wanted to achieve is,
- user clicked a link from tab 1
- and it will immediately display QTextBrowser in tab 2, at the html anchor i set.
Is there a way of doing this?
I've managed to switch tab by using tabWidget.setCurrentWidget()
now the question is, how to set the focus to the desired html anchor place of the QTextBrowser.
Thanks in advance.
Here's an example:
from tabwidget import Ui_MainWindow
import sys
from PyQt4 import QtGui, QtCore
class MyApp(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
QtCore.QObject.connect(self.ui.pushButton, QtCore.SIGNAL('clicked()'), self._show)
def _show(self):
self.ui.tabWidget.setCurrentWidget(self.ui.tab_2)
self.ui.textBrowser.setSource(QtCore.QUrl('text.html#anchor'))
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
mw = MyApp()
mw.show()
app.exec_()

Categories