PYQT: QTableView. Filter Between Dates - python

I've created a GUI that allows users to modify, filter update and delete from a sqlite database. Everything is working great except the date range filter. When I run the code, I don't get an error, I only get a blank filtered screen with no data. Does anyone see what's wrong with my code? [Section 1a, subgroup{v} is what I am seeking help on]. Thanks!
from PyQt4 import QtCore, QtGui, QtSql
import sys
import sqlite3
import time
import Search #imported ui.py MainWindow file
import os
try:
from PyQt4.QtCore import QString
except ImportError:
QString = str
class TableEditor(QtGui.QMainWindow, Search.Search_MainWindow):
def __init__(self, tableName, parent=None):
super(self.__class__, self).__init__()
self.setupUi(self)
self.model = QtSql.QSqlTableModel(self)
self.model.setTable('CAUTI')
self.model.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)
self.model.select()
self.model.setHeaderData(0, QtCore.Qt.Horizontal, "MRN")
self.model.setHeaderData(1, QtCore.Qt.Horizontal, "Last Name")
self.model.setHeaderData(2, QtCore.Qt.Horizontal, "First Name")
self.model.setHeaderData(3, QtCore.Qt.Horizontal, "Date of Event")
self.model.setHeaderData(4, QtCore.Qt.Horizontal, "Facility")
self.model.setHeaderData(5, QtCore.Qt.Horizontal, "Unit")
self.model.setHeaderData(6, QtCore.Qt.Horizontal, "User")
self.tableView.setModel(self.model)
self.setWindowTitle("HAI Table")
self.tableView.setColumnWidth(0,100)
self.tableView.setColumnWidth(1,100)
self.tableView.setColumnWidth(2,100)
self.tableView.setColumnWidth(3,100)
self.tableView.setColumnWidth(4,100)
self.tableView.setColumnWidth(5,100)
self.tableView.setColumnWidth(6,83)
self.submitButton.clicked.connect(self.submit)
self.revertButton.clicked.connect(self.model.revertAll)
self.quitButton.clicked.connect(self.close)
current = QtCore.QDateTime.currentDateTime()
self.startDate.setDate(current.date())
self.endDate.setDate(current.date())
self.startDate.setDisplayFormat("M/dd/yyyy")
self.endDate.setDisplayFormat("M/dd/yyyy")
# Section 1: Signals
# {i} Search Fields Button Emitted:
# [1]
self.search_MRN_Button.clicked.connect(self.search_MRN_FilterRecord)
# [2]
self.search_Lname_Button.clicked.connect(self.search_Lname_FilterRecord)
# [3]
self.search_Unit_Button.clicked.connect(self.search_Unit_FilterRecord)
# {ii} Search Clear Buttons Emitted:
# [1]
self.search_MRN_CancelButton.clicked.connect(self.search_MRN_CancelButton_Clicked)
# [2]
self.search_Lname_CancelButton.clicked.connect(self.search_Lname_CancelButton_Clicked)
# [3]
self.search_Unit_CancelButton.clicked.connect(self.search_Unit_CancelButton_Clicked)
# {iii} Search Fields Button Emitted:
# [1]
self.search_MRN.selectionChanged.connect(self.search_MRN_Edit)
# [2]
self.search_Lname.selectionChanged.connect(self.search_Lname_Edit)
# [3]
self.search_Unit.selectionChanged.connect(self.search_Unit_Edit)
# {iv} Search Fields Button Emitted:
# [1]
self.search_MRN.returnPressed.connect(self.search_MRN_Enter)
# [2]
self.search_Lname.returnPressed.connect(self.search_Lname_Enter)
# [3]
self.search_Unit.returnPressed.connect(self.search_Unit_Enter)
#{v} Search Between 2 Dates
self.btnSubmit.clicked.connect(self.FilterBetweenDates)
# Section 1a: Slots from Section 1.
#{i} Search Field Button Slots:
#[1]
def search_MRN_FilterRecord(self):
text = self.search_MRN.text()
if len(text) == 0:
self.model.setFilter("")
else:
self.model.setFilter("MRN like'" +self.search_MRN.text()+ "%%'")
#self.model.setFilter("MRN = '%s'" % text)
#[2]
def search_Lname_FilterRecord(self):
text = self.search_Lname.text()
if len(text) == 0:
self.model.setFilter("")
else:
self.model.setFilter("Surname like'" +self.search_Lname.text()+ "%'")
#self.model.setFilter("Surname = '%s'" % text) #This line of code will only pull exact matches.
#[3]
def search_Unit_FilterRecord(self):
text = self.search_Unit.text()
if len(text) == 0:
self.model.setFilter("")
else:
self.model.setFilter("Unit like'" +self.search_Unit.text()+ "%'")
#self.model.setFilter("Unit = '%s'" % text) #This line of code will only pull exact matches.
#{ii} Search Field Cancel Button Slots:
#[1]
def search_MRN_CancelButton_Clicked(self):
self.model.setFilter("")
self.search_MRN.setText("MRN Search")
#[2]
def search_Lname_CancelButton_Clicked(self):
self.model.setFilter("")
self.search_Lname.setText("Last Name Search")
#[3]
def search_Unit_CancelButton_Clicked(self):
self.model.setFilter("")
self.search_Unit.setText("Unit Search")
#{iii} Search Text Edited Slots:
#[1]
def search_MRN_Edit(self):
self.search_MRN.setText("")
#[2]
def search_Lname_Edit(self):
self.search_Lname.setText("")
#[3]
def search_Unit_Edit(self):
self.search_Unit.setText("")
#{iv} Search Text Return Pressed (Enter) Slots:
#[1]
def search_MRN_Enter(self):
self.search_MRN_FilterRecord()
#[2]
def search_Lname_Enter(self):
self.search_Lname_FilterRecord()
#[3]
def search_Unit_Enter(self):
self.search_Unit_FilterRecord()
#{v} Filter Between Dates, Slot:
def FilterBetweenDates(self):
start = str(self.startDate.text())
finish = str(self.endDate.text())
self.model.setFilter("EventDate BETWEEN'" + start and finish)
def submit(self):
self.model.database().transaction()
if self.model.submitAll():
self.model.database().commit()
else:
self.model.database().rollback()
QtGui.QMessageBox.warning(self, "HAI Table",
"The database reported an error: %s" % self.model.lastError().text())
def main():
app = QtGui.QApplication(sys.argv)
#app.setStyle( "Plastique" )
db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('HAI.db')
editor = TableEditor('CAUTI')
editor.show()
app.exec_()
if __name__ == '__main__':

The and in your filter text should part of the filter string. Now you are taking the logical-and of two strings (which will be the last string unless the first is empty) and append that to the filter string.
So change
self.model.setFilter("EventDate BETWEEN'" + start and finish)
to
filter = "EventDate BETWEEN '{}' AND '{}'".format(start, finish)
print(filter) # for debugging
self.model.setFilter(filter)
During debugging, it's probably a good idea to print the filter string and try it out in an SQL query (directly in the sqlite3 tool) so that you can see it works.

Related

adding dynamic data to sublcassed QAbstractTableModel

for testing purposes a have function that asks for input and displays it in a QListView
display data.
this works fine with one dim.data
I want to extend the script to display two-dimensional data
the incoming data should be inserted in the first row till column 3, and proceeds on the next rows (same operation) so the model contains the data in this form
input_values = [[1,2],
[1,2]]....
so far I implemented that the input_data is added into the first row, but the script stops running before it starts adding the data into the second row. I just get this info
Process finished with exit code -1073740791 (0xC0000409)
What is cousing this behavior and how to fix that ?
def thread_data_add(self, data):
if len(self.model.input_data[0]) <= 1:
self.model.input_data[0].append(data)
self.model.layoutChanged.emit()
elif len(self.model.input_data[0]) > 1:
self.model.input_data.append([])
self.model.input_data[1].append(data) #crashes here !!! need crash report
self.model.layoutChanged.emit()
full code
#!/usr/bin/env python
"""
"""
import threading
import sys
import logging
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg
class ViewModel(qtc.QAbstractTableModel):
def __init__(self, input_data=None):
super().__init__()
self.input_data = input_data or [[]]
#
def data(self, index, role): # parameter index, role are needed !
"""
:param index: Instance of QModelIndex Class / set automatically
Model indexes refer to items in models,
contain all the information required to specify their locations in those models
:param role: what type should be returned
:return: data as a string
"""
if role == qtc.Qt.DisplayRole:
row = index.row()
column = index.column()
text = self.input_data[row][column]
return text
def rowCount(self, index):
return len(self.input_data)
def columnCount(self, index):
return len(self.input_data[0])
def getData(self):
print(self.input_data)
# todo how to show list data
class MainWindow(qtw.QWidget):
core_signal = qtc.pyqtSignal(str)
def __init__(self):
super().__init__()
# View
table_view = qtw.QTableView()
self.model = ViewModel()
table_view.setModel(self.model)
# widgets
self.start_thread_button = qtw.QPushButton("start Thread")
self.test_button = qtw.QPushButton("display data")
# layout
qvboxlayout = qtw.QVBoxLayout()
qvboxlayout.addWidget(table_view)
qvboxlayout.addWidget(self.start_thread_button)
qvboxlayout.addWidget(self.test_button)
self.setLayout(qvboxlayout)
self.show()
# self.logger = self.default_logger()
# function
self.start_thread_button.clicked.connect(self.start)
self.test_button.clicked.connect(self.model.getData)
def lambda_thread_data_add(self, data):
if len(self.model.input_data[0]) <= 1:
self.model.input_data[0].append(data)
self.model.layoutChanged.emit()
# self.model.input_data.append([])
elif len(self.model.input_data[0]) > 1:
self.model.input_data.append([])
self.model.input_data[1].append(data) #crashes here !!! need crash report
self.model.layoutChanged.emit()
def thread_data_add(self, data):
if len(self.model.input_data[0]) <= 1:
self.model.input_data[0].append(data)
self.model.layoutChanged.emit()
# self.model.input_data.append([])
elif len(self.model.input_data[0]) > 1:
self.model.input_data.append([])
self.model.input_data[1].append(data) #crashes here !!! need crash report
self.model.layoutChanged.emit()
def start(self):
# starts thread
# Setting thread.daemon = True will allow the main program to exit before thread is killed.
threading.Thread(target=self._execute, daemon=True).start()
self.core_signal.connect(self.thread_data_add)
def _execute(self):
while True:
user_input = input("type in: ")
self.core_signal.emit(user_input) # transmit data
def default_logger(self,level=logging.DEBUG, save_path='beispiel.log'):
# create logger
custom_logger = logging.getLogger(__name__)
custom_logger.setLevel(level)
# was reingegeben werden soll
formatter = logging.Formatter('%(asctime)s;%(message)s;%(filename)s;%(lineno)d', "%Y-%m-%d %H:%M:%S")
file_handler = logging.FileHandler(save_path)
file_handler.setFormatter(formatter)
custom_logger.addHandler(file_handler)
stream_handler = logging.StreamHandler()
custom_logger.addHandler(stream_handler)
return custom_logger
if __name__ == '__main__':
app = qtw.QApplication(sys.argv)
w = MainWindow()
sys.exit(app.exec_())
The issue you are getting is an IndexError since the data is not being added uniformly (whole row at a time), it is being added one column, or cell, at a time. As a result, when starting the next row with the 3rd input, there is no data for the 2nd column in that row yet. You don't necessarily have to change the way you are inserting data, just catch the error and supply an empty string or None value.
def data(self, index, role):
if role == qtc.Qt.DisplayRole:
try:
text = self.input_data[index.row()][index.column()]
except IndexError:
text = None
return text
Additionally, make sure you are accessing the correct index of input_data in thread_data_add(), which would be the last index [-1] since you are appending data.
def thread_data_add(self, data):
if len(self.model.input_data[-1]) < 2:
self.model.input_data[-1].append(data)
else:
self.model.input_data.append([data])
self.model.layoutChanged.emit()

Program quit with error when using QCompleter

I'm writing a program with pyqt5 and want to make the QlineEdit show history input by using sqlite to store the inputs. I use a signal to catch the cursor when focusInEvent happens and select the history records at that time, then I put the results into QCompleter so it can pop up in QlineEdit. Now I can make the history inputs show in QlineEdit object but when I click on any value, 1s later, the whole program quit automatically with error, which says "Python has stopped".
class FocusLineEdit(QLineEdit):
ac = pyqtSignal(list)
def __init__(self, parent=None):
super(FocusLineEdit, self).__init__(parent)
self.ac.connect(self.addCompleter)
def focusInEvent(self, event):
rtl = call_history(self.objectName())
self.ac.emit(rtl)
def addCompleter(self, rtl):
self.autoCompleter = QCompleter(rtl)
self.autoCompleter.setCompletionMode(1)
self.setCompleter(self.autoCompleter)
def focusOutEvent(self, event):
pass
It is difficult to analyze where the problem is without you provide an MCVE, so my response implements what you require without taking into account your current code for it must meet the following requirements:
You must have 2 tables: objects and history that are related.
The table objects saves the name of the filtering history, it is similar to the use of the objectName that you use, but in general 2 widgets can access the same history if the connection establishes the same name
In the history table the information of the words associated with the id of the objects table is saved.
In my example I use the following instructions to create them:
CREATE TABLE IF NOT EXISTS objects (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE);
CREATE TABLE IF NOT EXISTS history (id INTEGER PRIMARY KEY AUTOINCREMENT, id_object INTEGER REFERENCES objects (id), word TEXT NOT NULL, UNIQUE (id_object, word));
Also to test it I created a data, if you already have data then you must eliminate the if test: and everything inside.
Finally for a better understanding of my solution I show a QTableView that is changing according to the selection.
from PyQt5 import QtCore, QtGui, QtWidgets, QtSql
def createConnection():
db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
db_path = 'test.db'
db.setDatabaseName(db_path)
if not db.open():
QMessageBox.critical(None, qApp.tr("Cannot open database"),
qApp.tr("Unable to establish a database connection.\n"
"This example needs SQLite support. Please read "
"the Qt SQL driver documentation for information "
"how to build it.\n\n"
"Click Cancel to exit."),
QMessageBox.Cancel)
return False
test = True
if test:
query = QtSql.QSqlQuery()
if not query.exec_('CREATE TABLE IF NOT EXISTS objects (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE);'):
return False
if not query.exec_('CREATE TABLE IF NOT EXISTS history (id INTEGER PRIMARY KEY AUTOINCREMENT, id_object INTEGER REFERENCES objects (id), word TEXT NOT NULL, UNIQUE (id_object, word));'):
return False
for i in range(3):
query.prepare('INSERT INTO objects (name) VALUES (?)')
query.addBindValue("obj{}".format(i))
if not query.exec_():
print(query.lastError().text())
import requests
import random
word_site = "http://svnweb.freebsd.org/csrg/share/dict/words?view=co&content-type=text/plain"
response = requests.get(word_site)
WORDS = response.content.decode().splitlines()
print(WORDS)
for i in range(3):
for text in random.sample(WORDS, 50):
query.prepare('INSERT INTO history (id_object, word) VALUES (?, ?)')
query.addBindValue(i+1)
query.addBindValue(text)
if not query.exec_():
print(query.lastError().text())
return True
class Completer(QtWidgets.QCompleter):
def __init__(self, parent=None):
super(Completer, self).__init__(parent)
self._last_words = []
def splitPath(self, path):
if path[-1] != ' ':
words = path.split()
self._last_words = words[:-1] if len(words) > 1 else []
return [words[-1]]
else:
QtCore.QTimer.singleShot(0, self.popup().hide)
return []
def pathFromIndex(self, index):
val = super(Completer, self).pathFromIndex(index)
return ' '.join(self._last_words + [val])
class HistoryManager(QtCore.QObject):
nameChanged = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(HistoryManager, self).__init__(parent)
model = QtSql.QSqlRelationalTableModel(self)
model.setTable("history")
model.setRelation(1, QtSql.QSqlRelation("objects", "id", "name"))
model.select()
self._proxy = QtCore.QSortFilterProxyModel(self)
self._proxy.setSourceModel(model)
self._proxy.setFilterKeyColumn(1)
# proxy.setFilterFixedString("obj1")
self._widgets = {}
self._completer = Completer(self)
self._completer.setModel(self._proxy)
self._completer.setCompletionColumn(2)
def register_widget(self, widget, objectname):
# TODO
if callable(getattr(widget, "setCompleter")):
widget.installEventFilter(self)
self._widgets[widget] = objectname
return True
return False
def eventFilter(self, obj, event):
if obj in self._widgets:
if event.type() == QtCore.QEvent.FocusIn:
name = self._widgets[obj]
self._proxy.setFilterFixedString(name)
obj.setCompleter(self._completer)
self.nameChanged.emit(name)
elif event.type() == QtCore.QEvent.FocusOut:
obj.setCompleter(None)
self._proxy.setFilterFixedString("")
self.nameChanged.emit("")
return super(HistoryManager, self).eventFilter(obj, event)
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self._manager = HistoryManager()
model = QtSql.QSqlRelationalTableModel(self)
model.setTable("history")
model.setRelation(1, QtSql.QSqlRelation("objects", "id", "name"))
model.select()
self._proxy = QtCore.QSortFilterProxyModel(self)
self._proxy.setSourceModel(model)
self._proxy.setFilterKeyColumn(1)
tv = QtWidgets.QTableView()
tv.setModel(self._proxy)
vlay = QtWidgets.QVBoxLayout()
for i in range(3):
le = QtWidgets.QLineEdit()
vlay.addWidget(le)
self._manager.register_widget(le, "obj{}".format(i))
vlay.addStretch()
lay = QtWidgets.QHBoxLayout(self)
lay.addWidget(tv, stretch=1)
lay.addLayout(vlay)
self._manager.nameChanged.connect(self._proxy.setFilterFixedString)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
if not createConnection():
sys.exit(-1)
manager = HistoryManager()
w = Widget()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())

PyQt4 How to send push button signal to another class in Python?

I need your advice and help for my code.
I am making a GUI program. Basically the program does the followings:
Gets input from the user
When a certain button is pushed, the program retrieves all the input and saved them in the database
The program does computations.
Shows the output
Here is the simple version of the program, calculator program:
As you can see in the figure, it takes 4 input from user, (1) any integer for var1, (2) any integer for var2, (3) operator (addition or subtraction) and (4) click button.
The GUI was designed using QtDesigner.
And here is my code:
import sys
import sqlite3
from PyQt4 import QtCore, QtGui
from testgui import Ui_MainWindow
class ShowAndInput(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
#connect to the database
self.connect_to_db()
#create table in the database
self.create_table()
#add items to the comboBox
self.add_items()
#calculate button to start calculating, gives signal to the next class Calculate
self.ui.pushButton_3.clicked.connect(self.calculate)
#close button to close the window
QtCore.QObject.connect(self.ui.pushButton,QtCore.SIGNAL("clicked()"), quit)
self.conn.close()
def connect_to_db(self):
self.conn = sqlite3.connect('testguidb.sqlite3')
self.cur = self.conn.cursor()
def create_table(self):
self.cur.execute('''CREATE TABLE IF NOT EXISTS Input (var1 INTEGER, var2 INTEGER)''')
self.conn.commit()
def add_items(self):
lst = ['addition', 'subtraction']
self.ui.comboBox.clear()
self.ui.comboBox.addItems(lst)
def calculate(self):
calculate = Calculate(self)
calculate.exec_()
So the purpose of the first class was to show the GUI and take input from the user. If user clicks the pushbutton named 'Calculate', it should connect to the new class named 'Calculate'.
Here is my code for the Calculate class:
class Calculate(QtGui.QMainWindow):
def __init__(self, parent = None):
QtGui.QWidget.__init__(parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
#validator to validate that the input is integer or digit
#connect to database
self.connect_to_db()
#get the input values and store them in the database
self.get_the_values()
#print the output
PrintOutcome()
def connect_to_db(self):
self.conn = sqlite3.connect('testguidb.sqlite3')
self.cur = self.conn.cursor()
def get_the_values(self):
dicti = {}
dicti['var1'] = self.ui.lineEdit.text()
dicti['var2'] = self.ui.lineEdit_2.text()
for key, val in sorted(dicti.items()):
key = str(key)
val = int(val)
self.cur.execute('INSERT OR IGNORE INTO Input (?) VALUES (?)',(key,val))
self.conn.commit()
And at the end of this class, it calls another class named 'PrintOutcome' to print out the result in the QTextBrowser. Here is the last piece of the code:
class PrintOutcome(QtGui.QMainWindow):
def __init__(self, parent = None):
QtGui.QWidget.__init__(parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
#connect to database
self.connect_to_db()
#get the value of the combobox
self.get_combox()
#print the output
if self.operator == 'addition': self.print_add()
elif self.operator == 'subtraction': self.print_sub()
def connect_to_db(self):
self.conn = sqlite3.connect('testguidb.sqlite3')
self.cur = self.conn.cursor()
def get_combox(self):
self.operator = str(self.ui.comboBox.currentText())
def print_add(self):
dicti={}
for i in range(2):
i = i + 1
dicti['var{0}'.format(i)] = self.cur.execute('SELECT var{0} FROM Input'.format(i))
dicti['var{0}'.format(i)] = int(self.cur.fetchone()[0])
text = str(dicti['var{0}'.format(i)])
self.ui.textBrowser.append(text)
result = dicti['var1'] + dicti['var2']
textsep = '-'*25+'(+)'
text = str(result)
self.ui.textBrowser.append(text)
self.ui.textBrowser.append(text)
def print_sub(self):
dicti={}
for i in range(2):
i = i + 1
dicti['var{0}'.format(i)] = self.cur.execute('SELECT var{0} FROM Input'.format(i))
dicti['var{0}'.format(i)] = int(self.cur.fetchone()[0])
text = str(dicti['var{0}'.format(i)])
self.ui.textBrowser.append(text)
result = dicti['var1'] + dicti['var2']
textsep = '-'*25+'(-)'
text = str(result)
self.ui.textBrowser.append(text)
self.ui.textBrowser.append(text)
if __name__=='__main__':
app = QtGui.QApplication(sys.argv)
myapp = ShowAndInput()
myapp.show()
sys.exit(app.exec_())
When I ran it, everything was fine. But when I pressed the calculate button, it returned an error message.
Here is the error message: RuntimeError: super-class init() of type Calculate was never called.
Any respond will be much appreciated. Thanks a lot.
Regards,
Arnold

Pop up warning box

I have a method that checks that a pyqt spinbox value has been entered, the required values are 1 through 18 inclusive so I initiate the spinbox with the value 0 so that I can easily tell its not been changed to the correct number. I thought that if the check finds its still 0 the user forget to set it and a warning pops up to let them know..
The problem I have is that the window pops up, user presses OK, the pop up closes but immediately opens again before the user has had time to set the correct value ... how can I have the pop up close and allow the user time to change the spinbox to the correct value before it checks for 0 and pops up again (if still not correct)
the signal that triggers group_check was originally triggering the pickFile method until I realised that the code executed whether Group No was set in the spinbox or not, I had tried to build the check into the pickFile method but then though it might be best to separate it out.
import sys
import time
from PyQt4 import QtGui, uic
import xlrd
import csv
import os
import re
qtCreatorFile = "UI1.ui" # Enter file here.
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
class MyApp(QtGui.QMainWindow, Ui_MainWindow):
group = ''
group_1 = ''
Var_1 = ''
Var_2 = ''
Var_3 = ''
error_string = ''
def __init__(self):
QtGui.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
self.file_picker_button.clicked.connect(self.group_check)
self.radioButton_1.clicked.connect(self.onRadioButton1)
self.radioButton_2.clicked.connect(self.onRadioButton2)
self.radioButton_3.clicked.connect(self.onRadioButton3)
self.spinBox.valueChanged.connect(self.valuechange)
def group_check(self):
while True:
if self.spinBox.value() == 0:
error_string ='You must select your\nGroup No first ! ok ? '
self.error_msg(error_string)
else:
self.pickFile()
def pickFile(self):
while True:
filename = QtGui.QFileDialog.getOpenFileName(self, 'Open File', '.')
if 'Monday' in filename:
break
elif 'Monday' not in filename or filename == '':
error_string ='Wrong file ? \nWant to try again ?'
self.error_msg1(error_string)
else:
self.filename = filename
x = first_file()
x.csv_from_excel(filename)
def onRadioButton1(self, group):
MyApp.Var_1 = 'PGDE SECONDARY ONLY'
MyApp.Var_2 = 'MA4 ONLY'
MyApp.Var_3 = 'PGDE'
def onRadioButton2(self, group):
MyApp.Var_1 = 'PGDE PRIMARY ONLY'
MyApp.Var_2 = 'MA4 ONLY'
MyApp.Var_3 = 'PGDE'
def onRadioButton3(self, group):
MyApp.Var_1 = 'PGDE PRIMARY ONLY'
MyApp.Var_2 = 'PGDE SECONDARY ONLY'
MyApp.Var_3 = 'MA4'
def valuechange(self, value):
MyApp.group_1 = ('Group '+ str(self.spinBox.value()))
if self.spinBox.value() >= 10:
MyApp.group = "1-9 ONLY"
if self.spinBox.value() >= 1 and self.spinBox.value() <= 9:
MyApp.group = "10-18 ONLY"
def error_msg(self, error_string):
choice = QtGui.QMessageBox.question(self, 'Error!', error_string)
Instead of using while True just display the error message and return from the function. Make them click the button again after they fix the error
def group_check(self):
if self.spinBox.value() == 0:
error_string ='You must select your\nGroup No first ! ok ? '
self.error_msg(error_string)
return
self.pickFile()

Getting selected text (python-gtk)

I want to get selected text automatically in python, using gtk module.
There is a code to get selected text from anywhere:
#!/usr/bin/env python
import pygtk
pygtk.require('2.0')
import gtk
class GetSelectionExample:
# Signal handler invoked when user clicks on the
# "Get String Target" button
def get_stringtarget(self, widget):
# And request the "STRING" target for the primary selection
ret = widget.selection_convert("PRIMARY", "STRING")
return
# Signal handler called when the selections owner returns the data
def selection_received(self, widget, selection_data, data):
# Make sure we got the data in the expected form
if str(selection_data.type) == "STRING":
# Print out the string we received
print "STRING TARGET: %s" % selection_data.get_text()
elif str(selection_data.type) == "ATOM":
# Print out the target list we received
targets = selection_data.get_targets()
for target in targets:
name = str(target)
if name != None:
print "%s" % name
else:
print "(bad target)"
else:
print "Selection was not returned as \"STRING\" or \"ATOM\"!"
return False
def __init__(self):
# Create the toplevel window
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_title("Get Selection")
window.set_border_width(10)
window.connect("destroy", lambda w: gtk.main_quit())
vbox = gtk.VBox(False, 0)
window.add(vbox)
vbox.show()
# Create a button the user can click to get the string target
button = gtk.Button("Get String Target")
eventbox = gtk.EventBox()
eventbox.add(button)
button.connect_object("clicked", self.get_stringtarget, eventbox)
eventbox.connect("selection_received", self.selection_received)
vbox.pack_start(eventbox)
eventbox.show()
button.show()
window.show()
def main():
gtk.main()
return 0
if __name__ == "__main__":
GetSelectionExample()
main()
But i don't want to this exactly.
i dont want to click a button. I want to see the selected text only, not after a button clicking. When i start the program ; it must show me the selected text automatically (without clicking any button!).
I want to this exactly :
#!/usr/bin/env python
import pygtk
pygtk.require('2.0')
import gtk
class MyApp (object):
def __init__(self):
self.window=gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.connect("delete_event", gtk.main_quit )
self.entry = gtk.Entry()
try:
self.s_text=gtk.SelectionData.get_text
# i expect that : the selected text (from anywhere)
# but it returns me :
#<method 'get_text' of 'gtk.SelectionData' objects>
except:
self.s_text="it must be selected text"
self.entry.set_text("Selected Text is : %s" % self.s_text )
self.window.add(self.entry)
self.window.show_all()
def main(self):
gtk.main()
app=MyApp()
app.main()
This program must show me the selected text in the entry box automatically.
Only this. But i can't do!
i expect " gtk.SelectionData.get_text " will show me the selected text but it returns "<method 'get_text' of 'gtk.SelectionData' objects>" .
And also i tried self.s_text=gtk.SelectionData.get_text()
But it returns me :
self.s_text=gtk.SelectionData.get_text()
TypeError: descriptor 'get_text' of 'gtk.SelectionData' object needs an argument
How can i do this? And also i am a beginner python programmer; if u can write the code ; it will be very good for me :)
thanks a lot !!
self.s_text=gtk.SelectionData.get_text
Method get_text is not called yet! You are assigning self.s_text to the method(function) object itself. Which is converted to string in "Selected Text is : %s" % self.s_text
You should changed it to:
self.s_text=gtk.SelectionData.get_text()
EDIT: But since you need a SelectionData object to pass to this method, the whole idea is wrong. I combined you two codes as something working:
#!/usr/bin/env python
import pygtk
pygtk.require('2.0')
import gtk
class MyApp (object):
def __init__(self):
self.window=gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.connect("delete_event", gtk.main_quit )
self.entry = gtk.Entry()
self.window.selection_convert("PRIMARY", "STRING")
self.window.connect("selection_received", self.selection_received)
self.window.add(self.entry)
self.window.show_all()
# Signal handler called when the selections owner returns the data
def selection_received(self, widget, selection_data, data):
print 'selection_data.type=%r'%selection_data.type
# Make sure we got the data in the expected form
if str(selection_data.type) == "STRING":
self.entry.set_text("Selected Text is : %s" % selection_data.get_text())
elif str(selection_data.type) == "ATOM":
# Print out the target list we received
targets = selection_data.get_targets()
for target in targets:
name = str(target)
if name != None:
self.entry.set_text("%s" % name)
else:
self.entry.set_text("(bad target)")
else:
self.entry.set_text("Selection was not returned as \"STRING\" or \"ATOM\"!")
return False
def main(self):
gtk.main()
app=MyApp()
app.main()

Categories