QLineEdit returns empty string - python

I'm trying to access the text written in a QLineEdit from another class, but it is returning an empty string.
Here is a minimalistic functional piece of code (Python 2.7):
import sys
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtWidgets import *
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.createmenus()
self.initui()
self.central_widget = QStackedWidget()
self.setCentralWidget(self.central_widget)
testWidgets = Container0()
self.central_widget.addWidget(testWidgets)
def initui(self):
self.setWindowTitle("TestWindow")
self.show()
def createmenus(self):
viewFile = self.menuBar().addMenu("File")
expMenu = QMenu("Export", self)
expAct = QAction("Save", self)
expMenu.addAction(expAct)
expMenu.triggered[QAction].connect(self.export_config)
viewFile.addMenu(expMenu)
def export_config(self):
options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
fileName, _ = QFileDialog.getSaveFileName(self, "Save as", "C:/", "Text (*.txt);;All Files (*)",
options=options)
if fileName:
Export().export(fileName)
class Container0(QWidget):
def __init__(self):
super(QWidget, self).__init__()
self.mainlayout = QVBoxLayout(self)
self.vbox_layout = QVBoxLayout()
self.text1 = QLineEdit()
print self.text1
self.vbox_layout.addWidget(self.text1)
self.mainlayout.addLayout(self.vbox_layout)
class Export():
def export(self, path):
tw = Container0()
t1 = tw.text1
t1text = t1.text()
print t1
print t1text
print path
if __name__ == '__main__':
app = QApplication([])
window = MainWindow()
window.show()
sys.exit(app.exec_())
About the code:
First of all I create my QMainWindow, which calls the functions initui and createmenus. In the next class Container0 I implement the QLineEdit widget. I separated the classes because the application I'm writing has several windows and a toolbar with "next" and "back" buttons, which change the centralWidget to the class I saved the window I want to display next. (I hope this wasnt't a bad idea)
What I want to achieve
Currently when I write something into the QLineEdit and then go to the Menu "File -> Export -> Save" and insert a path, the code calls the class Export and its function export, which should read the string I wrote in the QLineEdit and print it among the path. The problem is that my output from my QLineEdit is an empty string. Furthermore, the function Export seems to create another instance from the QLineEdit. Note the different memory locations when I call print self.text1:
<PyQt5.QtWidgets.QLineEdit object at 0x0000000002968B88>
<PyQt5.QtWidgets.QLineEdit object at 0x0000000002968DC8>
<PyQt5.QtWidgets.QLineEdit object at 0x0000000002968DC8>
### <- This is the empty line
C:/123
This makes me wonder how I can call the QLineEdit string without creating another instance. Furthermore, is this a correct way to handle multiple windows?
TL,DR: QLineEdit returns an empty string. It should not. Suggestions about the code structure are also welcome. Thanks!

Each time you use the following expression:
some_variable = Container0()
you are creating a new container, so in your case the container created in the __init__ of MainWindow is different from the one created in the export method of Export. Therefore, even if you place text in the main window, there is no text in the other Container.
The solution is to make testWidgets member of the class and pass the text content to export:
import sys
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtWidgets import *
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.createmenus()
self.initui()
self.central_widget = QStackedWidget()
self.setCentralWidget(self.central_widget)
self.testWidgets = Container0()
self.central_widget.addWidget(self.testWidgets)
def initui(self):
self.setWindowTitle("TestWindow")
self.show()
def createmenus(self):
viewFile = self.menuBar().addMenu("File")
expMenu = QMenu("Export", self)
expAct = QAction("Save", self)
expMenu.addAction(expAct)
expMenu.triggered[QAction].connect(self.export_config)
viewFile.addMenu(expMenu)
def export_config(self):
options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
fileName, _ = QFileDialog.getSaveFileName(self, "Save as", "C:/", "Text (*.txt);;All Files (*)",
options=options)
if fileName:
Export().export(fileName, self.testWidgets.text1.text())
class Container0(QWidget):
def __init__(self):
super(QWidget, self).__init__()
self.mainlayout = QVBoxLayout(self)
self.vbox_layout = QVBoxLayout()
self.text1 = QLineEdit()
print(self.text1)
self.vbox_layout.addWidget(self.text1)
self.mainlayout.addLayout(self.vbox_layout)
class Export():
def export(self, path, t1text):
print(t1text)
print(path)
if __name__ == '__main__':
app = QApplication([])
window = MainWindow()
window.show()
sys.exit(app.exec_())

Related

How to transfer QLineEdit value into console?

Assume we have an interface with Buttons and LineEdits in one .py file. I have this code in another, which inherits it:
import Inter_Input_Blasting as interf
from PyQt6 import QtCore,QtWidgets,QtGui
from functools import partial
class MainWindow(QtWidgets.QMainWindow):
def on_clicked(self):
print("Button Pushed")
def __init__(self,parent=None):
super(MainWindow, self).__init__(parent)
self.ui = interf.Ui_MainWindow()
self.ui.setupUi(self)
self.ui.calc_button.clicked.connect(MainWindow.on_clicked)
self.ui.input_overall_1.textChanged.connect(MainWindow.gather_data)
def gather_data(self):
return self.ui.input_overall_1.text()
if __name__== "__main__":
import sys
app = interf.QtWidgets.QApplication(sys.argv)
Form = MainWindow()
Form.show()
sys.exit(app.exec())
So, i need to print my values into console when i put it in the lineedit fiels. The .textChanged() method is working, but the .gather_data() isn't.
Provide a variable for storing the text:
def __init__(self,parent=None):
self.txt = None
Then in method gather_data, store the text in that variable:
def gather_data(self):
sef.txt = self.ui.input_overall_1.text()
then before sys.exit, print that value:
r = app.exec()
print(Form.txt)
sys.exit(r)

Transfer file path to another class and add items to a list

I have a menubar in the mainwindow class which I want to use to select a file directory. Once the file directory is selected it should call a function in the ui class to load the filenames into the list box. The filepath is being sent to the other function but the list doesn't load any items. My code is below thanks in advance.
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import *
import sys
import os
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.ui_widget = ui(parent=self)
self.setCentralWidget(self.ui_widget)
# filling up a menu bar
bar = self.menuBar()
# File menu
file_menu = bar.addMenu('File')
# adding actions to file menu
images_dir = QtWidgets.QAction('Set Images Dir', self)
close_action = QtWidgets.QAction('Close', self)
file_menu.addAction(images_dir)
# use `connect` method to bind signals to desired behavior
close_action.triggered.connect(self.close)
images_dir.triggered.connect(self.set_images_dir)
def set_images_dir(self):
filepath = QFileDialog.getExistingDirectory(self,"Select Directory")
if filepath:
filepath=filepath+'/'
ui().image_dir_select(filepath)
self.image_dir=filepath
return
class ui(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
QWidget.__init__(self)
layout = QGridLayout()
self.setLayout(layout)
self.listwidget = QListWidget()
layout.addWidget(self.listwidget)
def image_dir_select(self, image_dir):
filelist=os.listdir(image_dir)
self.listwidget.clear()
filelist=list(set(filelist))
filelist.sort()
self.listwidget.addItems(filelist)
app = QApplication(sys.argv)
screen = MainWindow()
screen.show()
sys.exit(app.exec_())
You have to call the image_dir_select of the existing ui_widget, but you're doing it against a new instance.
Change this:
ui().image_dir_select(filepath)
To this:
self.ui_widget.image_dir_select(filepath)

Python PyQt4: Single child window

I have a simple PyQt4 example.
When run, it displays a QMainWindow with a button.
If you click the button, then a second QMainWindow is created.
If you click it again, you get 2 second windows.
What is an elegant and simple way to prevent more than 1 second window in this example?
import sys
from PyQt4.QtGui import *
class win2(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self,parent)
layout = QVBoxLayout()
label = QLabel(self)
label.setText('This is win2')
layout.addWidget(label)
self.adjustSize()
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
layout = QVBoxLayout()
button1 = QPushButton("win2", self)
layout.addWidget(button1)
button1.clicked.connect(self.showwin2)
def showwin2(self):
w2 = win2(self)
w2.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())
Your Function creates a new instance of the class win2 each time the button is pressed. To Supress this behavior only call the show and raise_ functions instead of creating a new instance.
I would create the class as follows, and only use the button to 'show' the window. Tested and works as intended. Also consider using self when assigning your variables so they can be accessed throughout the class instance.
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
layout = QVBoxLayout()
button1 = QPushButton("win2", self)
layout.addWidget(button1)
button1.clicked.connect(self.showwin2)
self.w2 = win2(self)
def showwin2(self):
self.w2.show()
self.w2.raise_()

PyQt: How to add new tabs to QTextEdit?

I need to add a new tab, but I am having problems. I want to add new tabs in the main window, and keep the methods of the class Editor(). I can do this without having to create the class Editor() but need it to be so. Sorry for my English.
This is my code:
from PyQt4 import QtGui
from PyQt4 import QtCore
class Main(QtGui.QMainWindow):
def __init__(self):
super(Main, self).__init__()
self.initUi()
def initUi(self):
self.setWindowTitle("Editor")
self.resize(640, 480)
self.edit = Editor()
newAc = QtGui.QAction('New', self)
newAc.setShortcut('Ctrl+N')
newAc.triggered.connect(self.new_)
menu = self.menuBar()
filemenu = menu.addMenu('&File')
filemenu.addAction(newAc)
self.tab = QtGui.QTabWidget(self)
self.setCentralWidget(self.tab)
class Editor(QtGui.QTextEdit):
def __init__(self, parent=None):
super(Editor, self).__init__(parent)
def new_(self):
tab = QtGui.QTextEdit(self.tab)
self.tab.addTab(tab, 'Untitled')
def main():
import sys
app = QtGui.QApplication(sys.argv)
w = Main()
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
If you want to have the same text on both (or more) tabs you can use the same Editor class, but if not, you need instantiate an Editor object for each tab.
Also your code have some problems:
1- You are handling the tabs inside Editor objects. Instead, you must handle tabs at Main level.
2- The "default" tab you're adding when you create the Main object do not have any related QTextEdit change:
self.tab = QtGui.QTabWidget(self)
self.setCentralWidget(self.tab) # <---- tab without QTextEdit
add this:
self.tab = QtGui.QTabWidget(self)
self.editor = Editor(self.tab) # editor receives self.tab widget as parent.
self.setCentralWidget(self.tab)
also you will need define Editor class before Main.
3- Main object don't have any method called new_, Editor does. So the line:
newAc.triggered.connect(self.new_)
it's wrong.
So your code might look like:
from PyQt4 import QtGui
from PyQt4 import QtCore
class Editor(QtGui.QTextEdit):
def __init__(self, parent=None):
super(Editor, self).__init__(parent)
class Main(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
self.initUi()
def initUi(self):
self.setWindowTitle("Editor")
self.resize(640, 480)
newAc = QtGui.QAction('New', self)
newAc.setShortcut('Ctrl+N')
newAc.triggered.connect(self.new_)
menu = self.menuBar()
filemenu = menu.addMenu('&File')
filemenu.addAction(newAc)
self.tab = QtGui.QTabWidget(self)
self.setCentralWidget(self.tab)
self.tab.addTab(Editor(), "New Text")
def new_(self):
self.tab.addTab(Editor(), "New text")
def main():
import sys
app = QtGui.QApplication(sys.argv)
w = Main()
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()

AutoCompletion pops up on focusIn but cannot set text in QLineEdit from selection

from PyQt4.Qt import Qt, QObject,QLineEdit
from PyQt4 import QtGui, QtCore
import utils
class DirLineEdit(QLineEdit, QtCore.QObject):
"""docstring for DirLineEdit"""
def __init__(self):
super(DirLineEdit, self).__init__()
self.xmlDataObj = utils.ReadWriteCustomPathsToDisk()
self.defaultList = self.xmlDataObj.xmlData().values()
self._pathsList()
def focusInEvent(self, event):
self.completer().complete()
def _pathsList(self):
completerList = QtCore.QStringList()
for i in self.defaultList:
completerList.append(QtCore.QString(i))
lineEditCompleter = QtGui.QCompleter(completerList)
self.setCompleter(lineEditCompleter)
def __dirCompleter(self):
dirModel = QtGui.QFileSystemModel()
dirModel.setRootPath(QtCore.QDir.currentPath())
dirModel.setFilter(QtCore.QDir.AllDirs | QtCore.QDir.NoDotAndDotDot | QtCore.QDir.Files)
dirModel.setNameFilterDisables(0)
completer = QtGui.QCompleter(dirModel, self)
completer.setModel(dirModel)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.setCompleter(completer)
app = QtGui.QApplication(sys.argv)
smObj = DirLineEdit()
smObj.show()
app.exec_()
The above code works except I cannot set the text from the selection I make in the AutoComplete that pops up on focus in event .. Any idea why I am not able to make set text of the selected by completer ?
The problem is that your reimplementation of focusInEvent does not call its baseclass method. You should always do this unless you are certain you want to completely override the default behaviour. In this particular case, it's also important to call the baseclass focusInEvent method before invoking the completer, because that will obviously re-take the focus.
Here's a working demo that fixes the problems in the example code:
from PyQt4 import QtGui, QtCore
class LineEdit(QtGui.QLineEdit):
def __init__(self, strings, parent):
QtGui.QLineEdit.__init__(self, parent)
self.setCompleter(QtGui.QCompleter(strings, self))
def focusInEvent(self, event):
QtGui.QLineEdit.focusInEvent(self, event)
self.completer().complete()
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
strings = 'one two three four five six seven eight'.split()
self.edit1 = LineEdit(strings, self)
self.edit2 = LineEdit(strings, self)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.edit1)
layout.addWidget(self.edit2)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())

Categories