I currently have a hidden QWidget, which contains a QLineEdit
Upon showing that hidden QWidget, I want the cursor to be on the QLineEdit. Any help with implementation?
This class is shown when a button is clicked in an earlier class
class showInfo(QtGui.QWidget):
def __init__(self, parent=None):
super(showInfo, self).__init__(parent)
showName = QtGui.QLabel("Name of Show:")
self.showNameEdit = QtGui.QLineEdit()
self.showNameEdit.setCursorPosition(0) #THIS SHOULD WORK
self.mainLayout = QtGui.QGridLayout()
self.mainLayout.addWidget(self.showNameEdit)
self.setLayout(self.mainLayout)
try calling self.showNameEdit.setFocus()
Related
from PyQt6.QtWidgets import (
QMainWindow, QApplication, QDialog, QDialogButtonBox, QLabel, QTextEdit, QPushButton, QMessageBox, QMdiArea,
QTableWidgetItem, QStackedWidget
)
from PyQt6 import uic
import sys
class UI(QMainWindow):
def __init__(self):
super(UI, self).__init__()
uic.loadUi(r"C:\Users\csc\Documents\Rentour\front.ui", self)
self.show()
# define widgets
self.button = self.findChild(QPushButton, "signinButton")
self.signinButton.clicked.connect(self.OpenSignUp)
def OpenSignUp(self):
Sign_Up = Second()
widget.addWidget(Sign_Up)
widget.setCurrentIndex(widget.currentIndex()+1)
class Second(QMainWindow):
def __init__(self):
super(Second, self).__init__()
uic.loadUi(r"C:\Users\csc\Documents\Rentour\signpopup.ui", self)
# define widgets
self.button = self.findChild(QPushButton, "SubmitSignButton")
self.SubmitSignButton.clicked.connect(self.SignUpSave)
def SignUpSave(self):
email =self.EmailLine.text()
phoneno =self.PhonenoLine.text()
name =self.NameLine.text()
password = self.PasswordLine.text()
print(password)
app = QApplication(sys.argv)
mainwindow = UI()
widget = QStackedWidget()
widget.addWidget(mainwindow)
widget.show()
app.exec()
this is my code. Am trying to create a login/signup page. So when i click the signinButton, i want it to load the ui for the page which will have a bunch of line edits whose inputs im attempting to store in variables.
The ui files were made using qt designer and and i made this file from scratch. I also referred code with Hala(Youtuber). I Am trying to create a login/signup page. So when i click the signinButton, i want it to load the ui for the page which will have a bunch of line edits whose inputs im attempting to store in variables.
The problem is in your OpenSignUp function. The line widget.addWidget(Sign_Up) is not a valid command for a couple of reasons.
Also Sign_Up varable is holding a newly constructed QMainWindow, which are meant to be top level widgets and shouldn't be added to a layout.
It isn't totally clear what you are trying to achieve, but I am going to assume that you are trying to launch a secondary sign in window, In which case you want to use the open() method to launch the new window.
For example:
def OpenSignUp(self):
self.Sign_Up = Second()
self.Sign_Up.open()
Since you are using a stacked widget it is also possible that your goal is to simply switch to a different widget in the same window. In which case your Second class should probably just be a standard QWidget, and not a QMainWindow. and your stacked widget should be set as the central widget of your UI class.
So that would probably look something like this:
from PyQt6.QtWidgets import (
QMainWindow, QApplication, QDialog, QDialogButtonBox, QLabel, QTextEdit, QPushButton, QMessageBox, QMdiArea,
QTableWidgetItem, QStackedWidget
)
from PyQt6 import uic
import sys
class UI(QMainWindow):
def __init__(self):
super(UI, self).__init__()
# uic.loadUi(r"C:\Users\csc\Documents\Rentour\front.ui", self)
self.widget = QStackedWidget()
self.widget.addWidget(mainwindow)
self.setCentralWidget(self.widget)
self.Sign_Up = Second()
self.widget.addWidget(self.Sign_Up)
# define widgets
self.button = self.findChild(QPushButton, "signinButton")
self.signinButton.clicked.connect(self.OpenSignUp)
def OpenSignUp(self):
self.widget.setCurrentIndex(widget.currentIndex()+1)
class Second(QWidget):
def __init__(self):
super(Second, self).__init__()
uic.loadUi(r"C:\Users\csc\Documents\Rentour\signpopup.ui", self)
# define widgets
self.button = self.findChild(QPushButton, "SubmitSignButton")
self.SubmitSignButton.clicked.connect(self.SignUpSave)
def SignUpSave(self):
email =self.EmailLine.text()
phoneno =self.PhonenoLine.text()
name =self.NameLine.text()
password = self.PasswordLine.text()
print(password)
app = QApplication(sys.argv)
mainwindow = UI()
mainwindow.show()
app.exec()
Except you will need to rearrange the .ui file for UI class so that it is applied on top of the stacked widget as well.
I am making a GUI with PyQt, and I am having issues with my MainWindow class. The window doesn't show widgets that I define in other classes, or it will show a small portion of the widgets in the top left corner, then cut off the rest of the widget.
Can someone please help me with this issue?
Here is some example code showing my issue.
import sys
from PyQt4 import QtGui, QtCore
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent=parent)
self.resize(300, 400)
self.centralWidget = QtGui.QWidget(self)
self.hbox = QtGui.QHBoxLayout(self.centralWidget)
self.setLayout(self.hbox)
names = ['button1', 'button2', 'button3']
testButtons = buttonFactory(names, parent=self)
self.hbox.addWidget(testButtons)
class buttonFactory(QtGui.QWidget):
def __init__(self, names, parent=None):
super(buttonFactory, self).__init__(parent=parent)
self.vbox = QtGui.QVBoxLayout()
self.setLayout(self.vbox)
for name in names:
btn = QtGui.QPushButton(name)
self.vbox.addWidget(btn)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
gui = MainWindow()
gui.show()
app.exec_()
A QMainWindow has a central widget that is a container in which you should add your widgets. It has its own layout. The layout of the QMainWindow is for toolbars and such. The centralWidget must be set with the setCentralWidget method. It isn't enough to just call it self.centralWidget
Use the following three lines instead.
self.setCentralWidget(QtGui.QWidget(self))
self.hbox = QtGui.QHBoxLayout()
self.centralWidget().setLayout(self.hbox)
I have some trouble customizing a class including a QPushButton and QLabel, and I just want to set the QPushButton checkable and define a slot to its toggled signal, in addition, the custom class inherents QObject.
The code is shown below,
import sys
from PyQt5 import QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import pyqtSlot, QObject
class CustomButton(QPushButton):
def __init__(self, label='', parent=None):
super().__init__(label, parent)
self.setCheckable(True)
self.toggled.connect(self.update)
def update(self, state):
if state:
self.setStyleSheet('background-color: green')
else:
self.setStyleSheet('background-color: red')
class ButtonCtrl(QObject):
def __init__(self, parent=None, label=''):
super().__init__()
if isinstance(parent, QLayout):
col = QVBoxLayout()
parent.addLayout(col)
else:
col = QVBoxLayout(parent)
self.text = ['ON', 'OFF']
self.label = QLabel(label)
self.button = QPushButton('ON')
# self.button = CustomButton('ON')
col.addWidget(self.label)
col.addWidget(self.button)
self.button.setCheckable(True)
self.button.setChecked(True)
self.button.toggled.connect(self.update)
self.update(True)
self.label.setFont(QFont('Microsoft YaHei', 14))
self.button.setFont(QFont('Microsoft YaHei', 12, True))
self.button.toggle()
# #pyqtSlot(bool)
def update(self, state):
if state:
self.button.setText(self.text[0])
self.button.setStyleSheet('background-color: green')
else:
self.button.setText(self.text[-1])
self.button.setStyleSheet('background-color: red')
class Window(QWidget):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
# set the layout
layout = QVBoxLayout(self)
but = ButtonCtrl(layout, "Test")
#self.but = ButtonCtrl(layout, "Test")
btn = CustomButton()
layout.addWidget(btn)
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyle('Fusion')
main = Window()
main.show()
sys.exit(app.exec_())
I have customized two buttons, named CustomButton(QPushButton) and ButtonCtrl(QObject), and I have tested the slot in the main window, however the background update slot works for CustomButton(QPushbutton) and does not work for ButtonCtrl(QObject), the slot function is not even invoked.
However, if I change the button member of ButtonCtrl(QObject) from QPushButton into my CustomButton(QPushButton), the it will work well in the main window. Furthermore, if the but in main window becomes a member of the main window class by setting self.but=ButtonCtrl(layout, "Test"), it will work as well.
I didn't find direct answer to it in Qt documentation which explains that
Signals are emitted by an object when its internal state has changed in some way that might be interesting to the object's client or owner. Signals are public access functions and can be emitted from anywhere, but we recommend to only emit them from the class that defines the signal and its subclasses.
I am not sure if the lifetime of the but causing this effect, hope to get an answer, thank you.
The problem is simple: The ButtonCtrl class object has a local scope so it will be destroyed, and why doesn't the same happen with the CustomButton class object? Well, because the ownership of a QWidget has its parent, and the parent of that button is the window, instead the ButtonCtrl object does not have it. In this case the solution is to extend the life cycle of the variable, and in the case of a QObject there are several options:
make the class member variable,
Place it in a container with a longer life cycle, or
establish a QObject parent with a longer life cycle.
Using the third alternative is just to change to:
class ButtonCtrl(QObject):
def __init__(self, parent=None, label=''):
super().__init__(parent)
# ...
The first option is the one commented on in your code:
self.but = ButtonCtrl(layout, "Test")
and the second is similar:
self.container = list()
but = ButtonCtrl(layout, "Test")
self.container.append(but)
I am new to Qt/PySide. I want QLineEdit to select all text in it when it gets focus. After getting focus and selecting all text, it should select all text only after focus is lost and gained again. It should not select all text when I change cursor position after QLineEdit gains focus. How do I do that?
Update: My current code improved as suggested by Ashwani Kumar. I still can't get it to work though:
import sys
from PySide.QtGui import QLineEdit, QApplication, QVBoxLayout, QWidget
class MyLineEdit(QLineEdit):
def __init__(self, parent=None):
super(MyLineEdit, self).__init__(parent)
def focusInEvent(self, e):
self.selectAll()
app = QApplication(sys.argv)
top = QWidget()
layout = QVBoxLayout()
layout.addWidget(MyLineEdit())
layout.addWidget(MyLineEdit())
top.setLayout(layout)
top.show()
app.exec_()
With focusInEvent, when you click the widget, it gets executed, but since you click, it removes the selected text.
To overcome this, we must use the mousePressEvent, this can be done two ways:
import sys
from PySide.QtGui import QLineEdit, QApplication, QVBoxLayout, QWidget
class MyLineEdit(QLineEdit):
def __init__(self, parent=None):
super(MyLineEdit, self).__init__(parent)
def mousePressEvent(self, e):
self.selectAll()
app = QApplication(sys.argv)
top = QWidget()
layout = QVBoxLayout()
layout.addWidget(MyLineEdit())
layout.addWidget(MyLineEdit())
top.setLayout(layout)
top.show()
app.exec_()
Or you can do it by simply overriding the base QLineEdit class:
txt_demo = QtGui.QLineEdit()
txt_demo.mousePressEvent = lambda _ : txt_demo.selectAll()
However, since we are modifying the mousePressEvent, whenever you try to click text, it will always select all first.
For future visitors, I am posting code that is working for me. As I am a newbie I am not sure if the code contains any malpractices. If it does feel free to comment and I'll update my code/answer. Code:
import sys
from PySide.QtGui import QLineEdit, QApplication, QVBoxLayout, QWidget
class LineEdit(QLineEdit):
def __init__(self, parent=None):
super(LineEdit, self).__init__(parent)
self.readyToEdit = True
def mousePressEvent(self, e, Parent=None):
super(LineEdit, self).mousePressEvent(e) #required to deselect on 2e click
if self.readyToEdit:
self.selectAll()
self.readyToEdit = False
def focusOutEvent(self, e):
super(LineEdit, self).focusOutEvent(e) #required to remove cursor on focusOut
self.deselect()
self.readyToEdit = True
app = QApplication(sys.argv)
top = QWidget()
layout = QVBoxLayout()
layout.addWidget(LineEdit())
layout.addWidget(LineEdit())
top.setLayout(layout)
top.show()
app.exec_()
You have to subclass the QLineEdit and then use the new class instead of QLineEdit.
e.g: -
class MyLineEdit(QtGui.QLineEdit):
def __init__(self, parent=None)
super(MyLineEdit, self).__init__(parent)
def focusInEvent(self, e):
self.selectAll()
lineedit = MyLineEdit()
QTimer solution as seen on QtCentre:
import types
from PyQt4 import QtCore
def bind(func, to):
"Bind function to instance, unbind if needed"
return types.MethodType(func.__func__ if hasattr(func, "__self__") else func, to)
...
self.txtSrc.focusInEvent = bind(lambda w, e: QtCore.QTimer.singleShot(0, w.selectAll), self.txtSrc)
Also the provided solution doesn't require to subclass QLineEdit.
These answers don't really provide the sort of standard ergonomics you'd probably want (and users might expect). For example, if you single-click once on a QLE which is not currently all-selected, and then single-click again, typically you'd want the first click to select-all, and the second click to allow you to place the cursor in the specific spot you have chosen.
This can be achieved simply by doing this:
def mousePressEvent(self, event):
already_select_all = self.text() == self.selectedText()
super().mousePressEvent(event)
if not already_select_all:
self.selectAll()
The question in fact asks about gaining focus, not specifically by mouse-clicking, and indeed, if you are a keyboardist or generally musophobic you'll probably also want the whole text to be selected any time the QLE gains focus, e.g. by tabbing or by use of a QLabel "buddy" mnemonic. This seems to do the job:
class MyLineEdit(QtWidgets.QLineEdit):
def __init__(self, *args):
super().__init__(*args)
self.focus_in_reason = None
def focusInEvent(self, event):
super().focusInEvent(event)
self.selectAll()
self.focus_in_reason = event.reason()
def mousePressEvent(self, event):
super().mousePressEvent(event)
if self.focus_in_reason == QtCore.Qt.MouseFocusReason:
self.selectAll()
self.focus_in_reason = None
I am trying to implement a function. My code is given below.
I want to get the text in lineedit with objectname 'host' in a string say 'shost' when the user clicks the pushbutton with name 'connect'. How can I do this? I tried and failed. How do I implement this function?
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class Form(QDialog):
def __init__(self, parent=None):
super(Form, self).__init__(parent)
le = QLineEdit()
le.setObjectName("host")
le.setText("Host")
pb = QPushButton()
pb.setObjectName("connect")
pb.setText("Connect")
layout.addWidget(le)
layout.addWidget(pb)
self.setLayout(layout)
self.connect(pb, SIGNAL("clicked()"),self.button_click)
self.setWindowTitle("Learning")
def button_click(self):
#i want the text in lineedit with objectname
#'host' in a string say 'shost'. when the user click
# the pushbutton with name connect.How do i do it?
# I tried and failed. How to implement this function?
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
Now how do I implement the function "button_click" ? I have just started with pyQt!
My first suggestion is to use Qt Designer to create your GUIs. Typing them out yourself sucks, takes more time, and you will definitely make more mistakes than Qt Designer.
Here are some PyQt tutorials to help get you on the right track. The first one in the list is where you should start.
A good guide for figuring out what methods are available for specific classes is the PyQt4 Class Reference. In this case, you would look up QLineEdit and see the there is a text method.
To answer your specific question:
To make your GUI elements available to the rest of the object, preface them with self.
import sys
from PyQt4.QtCore import SIGNAL
from PyQt4.QtGui import QDialog, QApplication, QPushButton, QLineEdit, QFormLayout
class Form(QDialog):
def __init__(self, parent=None):
super(Form, self).__init__(parent)
self.le = QLineEdit()
self.le.setObjectName("host")
self.le.setText("Host")
self.pb = QPushButton()
self.pb.setObjectName("connect")
self.pb.setText("Connect")
layout = QFormLayout()
layout.addWidget(self.le)
layout.addWidget(self.pb)
self.setLayout(layout)
self.connect(self.pb, SIGNAL("clicked()"),self.button_click)
self.setWindowTitle("Learning")
def button_click(self):
# shost is a QString object
shost = self.le.text()
print shost
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
The object name is not very important.
what you should be focusing at is the variable that stores the lineedit object (le) and your pushbutton object(pb)
QObject(self.pb, SIGNAL("clicked()"), self.button_clicked)
def button_clicked(self):
self.le.setText("shost")
I think this is what you want.
I hope i got your question correctly :)
Acepted solution implemented in PyQt5
import sys
from PyQt5.QtWidgets import QApplication, QDialog, QFormLayout
from PyQt5.QtWidgets import (QPushButton, QLineEdit)
class Form(QDialog):
def __init__(self, parent=None):
super(Form, self).__init__(parent)
self.le = QLineEdit()
self.le.setObjectName("host")
self.le.setText("Host")
self.pb = QPushButton()
self.pb.setObjectName("connect")
self.pb.setText("Connect")
self.pb.clicked.connect(self.button_click)
layout = QFormLayout()
layout.addWidget(self.le)
layout.addWidget(self.pb)
self.setLayout(layout)
self.setWindowTitle("Learning")
def button_click(self):
# shost is a QString object
shost = self.le.text()
print (shost)
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
Short and general answer is:
self.input = QLineEdit()
your_text = self.input.text()