2017-10-12 7 views
1

Je suis en train de faire un exemple plus complet de semi-transparent highlights en utilisant des listes pour:Faits saillants semi-transparents à l'aide PySide et QTextEdit (version 2)

(1) total R, G, B, A, et mettre en évidence compte (cinq listes)

(2) moyenne R, G, B, A (quatre listes)

les valeurs dans la liste moyenne ils assignés en tant que couleurs d'arrière-plan. Les listes agrégées sont utilisées pour calculer la moyenne en ajoutant et en soustrayant des couleurs de surbrillance. Chaque liste contient autant d'éléments que de caractères dans le widget de texte. J'utilise une base de données pandas pour stocker les faits saillants en mémoire, car il peut y avoir une tonne d'entre eux à traiter de diverses façons ainsi que d'autres données finalement. Placer la souris sur un caractère affiche son emplacement, le nombre de surlignages et les valeurs RVBA. Sauf, un problème apparaît parfois - comme si un pinceau était traîné pendant une seconde lors du passage d'un emplacement de surbrillance à un autre. Regardez la couleur turquoise sur le "e" à la fin du texte "PySide.QtCore". Je pense que le problème est de savoir comment j'utilise l'ensemble et déplacer les positions du curseur - mais je ne suis pas certain. Dois-je réinitialiser la position du curseur après avoir ajouté chaque surbrillance? Est-ce que je ne sélectionne pas un seul caractère correctement?

import sys 
import pandas as pd 
import sqlite3 
from PySide.QtCore import * 
from PySide.QtGui import * 

def connect_database(db_file): 
    try: 
     conn = sqlite3.connect(db_file) 
     return conn 
    except Error as e: 
     print(e) 
     return None 

def create_data(connection): # database connection 
    c = connection.cursor() # database cursor 
    c.execute("CREATE TABLE sections(id INTEGER PRIMARY KEY, start INTEGER, end INTEGER, r INTEGER, g INTEGER, b INTEGER, a INTEGER)") 
    c.execute("INSERT INTO sections VALUES(1,0,20,100,200,100,100)") 
    c.execute("INSERT INTO sections VALUES(2,15,20,200,100,100,50)") 
    c.execute("INSERT INTO sections VALUES(3,18,30,100,100,200,100)") 
    c.execute("INSERT INTO sections VALUES(4,50,60,100,200,200,150)") 
    db.commit() 
    return c.lastrowid 


class QTextEdit2(QTextEdit): 

    def __init__(self, parent=None): 
     super().__init__(parent) 
     self.setMouseTracking(True) 
     self.cursor = self.textCursor() 

     self.length = len(self.toPlainText()) 
     self.bg_red = [0 for n in range(self.length)] # stores aggregate values of all highlights (not averages) 
     self.bg_green = [0 for n in range(self.length)] 
     self.bg_blue = [0 for n in range(self.length)] 
     self.bg_alpha = [0 for n in range(self.length)] 
     self.bg_count = [0 for n in range(self.length)] # number of highlights. if this is 0 then don't display 
                 # stored r,g,b just display white. in this example 
                 # only highlights are written. everything else stays 
                 # default 

     self.display_red = [0 for n in range(self.length)] # set to the value to display (average of highlights) 
     self.display_green = [0 for n in range(self.length)] 
     self.display_blue = [0 for n in range(self.length)] 
     self.display_alpha = [0 for n in range(self.length)] 

     self.sections = self.load_sections() 
     self.color_sections() 

    def mouseMoveEvent(self, event): 
     point = QPoint() 
     x = event.x() 
     y = event.y() 
     point.setX(x) 
     point.setY(y) 
     n = self.cursorForPosition(point).position() 
     print("%d: Section Count: %d RGBA: %d %d %d %d" % (n, self.bg_count[n],self.display_red[n], self.display_green[n],self.display_blue[n], self.display_alpha[n])) 
     super().mouseMoveEvent(event) 


    def load_sections(self): 
     c = sqlite3.connect("qda_test_01.sqlite") 
     df = pd.read_sql_query("SELECT * FROM sections", c) 
     return df 


    def blend_colors(self, start, end, r, g, b, a): 
     for n in range(start,end): 
      self.bg_red[n] = self.bg_red[n]+r 
      self.bg_green[n] = self.bg_green[n]+g 
      self.bg_blue[n] = self.bg_blue[n]+b 
      self.bg_alpha[n] = self.bg_alpha[n]+a 
      self.bg_count[n] = self.bg_count[n]+1 
      self.display_red[n] = self.bg_red[n]/self.bg_count[n] 
      self.display_green[n] = self.bg_green[n]/self.bg_count[n] 
      self.display_blue[n] = self.bg_blue[n]/self.bg_count[n] 
      self.display_alpha[n] = self.bg_alpha[n]/self.bg_count[n] 
      if self.display_red[n] > 255: # just in case RGBA data is weird... 
       self.display_red[n] = 255 
      if self.display_green[n] > 255: 
       self.display_green[n] = 255 
      if self.display_blue[n] > 255: 
       self.display_blue[n] = 255 
      if self.display_alpha[n] > 255: 
       self.display_alpha[n] = 255 
      if self.display_red[n] < 0: 
       self.display_red[n] = 0 
      if self.display_green[n] < 0: 
       self.display_green[n] = 0 
      if self.display_blue[n] < 0: 
       self.display_blue[n] = 0 
      if self.display_alpha[n] < 0: 
       self.display_alpha[n] = 0 

      print("LOCATION: %d | SECTION:  r:%d g:%g b:%d  a:%d  | DISPLAY:  r:%d g:%g b:%d  a:%d" % (n,self.bg_red[n],self.bg_green[n],self.bg_blue[n],self.bg_alpha[n],self.display_red[n],self.display_green[n],self.display_blue[n],self.display_alpha[n])) 

      color = QColor(self.display_red[n], self.display_green[n], self.display_blue[n]) 
      color.setAlpha(self.display_alpha[n]) 
      cursor = self.textCursor() 
      cursor.setPosition(n) 
      cursor.movePosition(QTextCursor.NextCharacter, QTextCursor.KeepAnchor, 1) 
      charfmt = cursor.charFormat() 
      charfmt.setBackground(color) 
      self.setCurrentCharFormat(charfmt) 
      self.setTextCursor(cursor) 


    def color_sections(self): 
     for n in range(self.sections.id.count()): 
      print("-----SECTION:%d-----" % (n)) 
      section = self.sections.iloc[n] 
      self.blend_colors(section.start, section.end, section.r, section.g, section.b, section.a) 



if __name__ == '__main__': 

    # Create database and sections to highlight 
    fn='qda_test_01.sqlite' 
    db=connect_database(fn) 
    id=create_data(db) 
    db.close() 

    app = QApplication(sys.argv) 
    window = QTextEdit2(
     "In addition, the PySide.QtCore.QPoint class provides the PySide.QtCore.QPoint.manhattanLength() function which gives an inexpensive approximation of the length of the PySide.QtCore.QPoint object interpreted as a vector. Finally, PySide.QtCore.QPoint objects can be streamed as well as compared.") 
    window.show() 
    sys.exit(app.exec_()) 
+0

Quelle est l'application pour cela? Quel est exactement le but de la surbrillance? Votre code est très difficile à comprendre sans contexte. – ekhumoro

+0

Mon code est également difficile à comprendre parce que je suis nouveau à Python et rouillé à la programmation en général. Chaque point culminant représente une catégorie attribuée par un ou plusieurs chercheurs. Les chercheurs reclasseront et même supprimeront les faits saillants qui chevauchent souvent plusieurs couches. Les utilisateurs peuvent changer les couleurs comme ils préfèrent. En sciences sociales, ce processus est appelé "[codage] (https://en.wikipedia.org/wiki/Coding_ (social_sciences))" interviews. Je soupçonne que mon problème est dans le setPosition, movePosition, définir des lignes de format. Mais, si le code est trop illisible, je peux essayer un exemple plus basique et re-poster. – davideps

+0

Le code semble fonctionner correctement lorsqu'il n'y a qu'un seul surbrillance. Donc, quelque chose tourne mal quand le processus a répété. – davideps

Répondre

1

Si vous aviez utilisé le code que je vous ai donné à mon previous answer, l'exemple actuel fonctionnerait correctement. Comme c'est le cas, vos modifications ont introduit beaucoup d'erreurs hors-par-un. Pour déboguer cela, vous devriez d'abord vérifier pour voir exactement quels blocs de texte doivent être mis en évidence. Prenant les 65 premiers caractères du texte et les valeurs de début/fin de la base de données, ce qui donne:

>>> t = "In addition, the PySide.QtCore.QPoint class provides the PySide." 
>>> t[0:20] 
'In addition, the PyS' 
>>> t[15:20] 
'e PyS' 
>>> t[18:30] 
'ySide.QtCore' 
>>> t[50:60] 
'es the PyS' 

Si vous comparez cela aux faits saillants de la production réelle, vous verrez qu'aucun du match des sections correctement (par exemple, regardez "S" dans chaque "PySide").

Pour que cela fonctionne correctement, vous devez obtenir le texte curseur une fois au début, l'utiliser pour faire toutes les modifications nécessaires, puis re-régler une fois à la fin:

Ceci est analogue à la mise à jour d'une base de données: vous utilisez un curseur pour planifier une série de modifications, puis les valider en une seule opération à la fin.

+0

Votre code corrige le problème et votre explication est très utile, en particulier en soulignant que setTextCursor est analogue à une validation de base de données. Étant donné que le contexte est un widget d'édition de texte, je m'attendais à ce que le «curseur» se comporte de manière identique au curseur dans un traitement de texte, avec cursor.setCharFormat ayant un effet immédiat.Comme j'ai essayé de faire fonctionner mon code, je me suis aventuré de plus en plus loin de votre code précédent. – davideps