I'm using gtk+-3.2.3 with css on Ubuntu natty. In the code below I have a button that starts out with a background color of green with blue text. When I hover over it the background color changes to red but the font color will not change to white as I've specified. Also when pressing and holding the button the background color changes to orange but the font color won't change to cyan that I've specified. Why is this happening? Is this the window manager over-riding my code?
/*Compile with:
gcc -Wall -o cssbutton2 `pkg-config --cflags --libs gtk+-3.0` cssbutton2.c
*/
#include <gtk/gtk.h>
int main(int argc, char *argv[] )
{
GtkWidget *window;
GtkWidget *button;
GtkCssProvider *provider;
GdkDisplay *display;
GdkScreen *screen;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window), 280, 200);
g_signal_connect (GTK_WIDGET (window), "destroy",
G_CALLBACK (gtk_main_quit), NULL);
button = gtk_button_new_with_label("CssButton");
gtk_widget_set_name (GTK_WIDGET(button), "mybutton");
gtk_widget_set_halign (GTK_WIDGET(button),GTK_ALIGN_CENTER);
gtk_widget_set_valign (GTK_WIDGET(button),GTK_ALIGN_CENTER);
gtk_widget_set_size_request(GTK_WIDGET(button), 200, 120);
gtk_container_add(GTK_CONTAINER(window),button);
provider = gtk_css_provider_new ();
display = gdk_display_get_default ();
screen = gdk_display_get_default_screen (display);
gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_USER);
gtk_css_provider_load_from_data (GTK_CSS_PROVIDER (provider),
" GtkWindow {\n"
" background-color: tan;\n"
"}\n"
" GtkButton {\n"
" -GtkWidget-focus-line-width: 0;\n"
" border-radius: 15;\n"
" font: Sans 23;\n"
" color: #00008B;\n"
" background-color: green;\n"
"}\n"
" .button:hover {\n"
" background-color: red;\n"
" color: white;\n"
"}\n"
" .button:hover:active {\n"
" background-color: orange;\n"
" color: cyan;\n"
"}\n", -1, NULL);
g_object_unref (provider);
gtk_widget_show_all(window);
gtk_main();
return(0);
}
I've just tested this on Ubuntu 12.04 (gtk+ 3.4.2) and after adding background-image: none; to the GtkButton style definition, this works as you describe is the desired behavior. Maybe just a bug in GTK that has since been fixed?
you can reference the gtk css style grammar:
https://developer.gnome.org/gtk3/stable/chap-css-overview.html
/*Compile with:
gcc -Wall -o cssbutton2 `pkg-config --cflags --libs gtk+-3.0` cssbutton2.c
*/
#include <gtk/gtk.h>
int main(int argc, char *argv[] )
{
GtkWidget *window;
GtkWidget *button;
GtkCssProvider *provider;
GdkDisplay *display;
GdkScreen *screen;
//GtkStyleContext *context;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window), 280, 200);
gtk_window_set_title(GTK_WINDOW(window),"CSSBUTTON");
g_signal_connect (GTK_WIDGET (window), "destroy",
G_CALLBACK (gtk_main_quit), NULL);
button = gtk_button_new_with_label("CssButton");
gtk_widget_set_name (GTK_WIDGET(button), "mybutton");
gtk_widget_set_halign (GTK_WIDGET(button),GTK_ALIGN_CENTER);
gtk_widget_set_valign (GTK_WIDGET(button),GTK_ALIGN_CENTER);
gtk_widget_set_size_request(GTK_WIDGET(button), 200, 120);
gtk_container_add(GTK_CONTAINER(window),button);
provider = gtk_css_provider_new ();
display = gdk_display_get_default ();
screen = gdk_display_get_default_screen (display);
// context = gtk_widget_get_style_context(window);
gtk_css_provider_load_from_data (provider,
"*{"
"color:green;"
"font-family:Monospace;"
"border:1px solid;"
" }"
" window {"
" background-color: rgba(50,30,70,100);"
" background-image:none;"
"}"
" button {"
" border-radius: 15px;"
" font: Sans 23;"
" color: #00008B;"
" background-color: green;"
" background-image:none;"
"}"
" button:hover {"
" background-color: red;"
" color: white;"
"}"
" button:hover:active {"
" background-color: orange;"
" color: cyan;"
"}", -1, NULL);
gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER(provider),GTK_STYLE_PROVIDER_PRIORITY_USER);
g_object_unref (provider);
gtk_widget_show_all(window);
gtk_main();
return(0);
}
Related
sorry I ask a lot of questions in this forum because I am really a beginner. So I have a body temperature and oxygen saturation monitoring tool project. I'm using nodemcu esp8266, sensor ds18b20, and sensor max30100. the configuration between the three tools has been successful, but when entering a coding program to send data to google firebase the oxygen saturation value cannot retrieve data repeatedly, for example as shown below. enter image description here
This my code :
//ESP8266 Based Patient Health Monitoring System
#include <ESP8266WebServer.h>
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#include <OneWire.h>
#include <DallasTemperature.h>
#include <FirebaseArduino.h>
#define FIREBASE_HOST "monitoring-oximeter-d2ff2-default-rtdb.firebaseio.com"
#define FIREBASE_AUTH "uxoi7mv66IxOBG5ZoGBJY51hPp0AfbYezmmeCkvu"
#define DS18B20 2 //D4 pin= GPIO pin 2
#define REPORTING_PERIOD_MS 1000
int BPM, SpO2, bodytemperature;
/*Put your SSID & Password*/
const char* ssid = "HAURA"; // Enter SSID here
const char* password = "13131313"; //Enter Password here
PulseOximeter pox;
uint32_t tsLastReport = 0;
OneWire oneWire(DS18B20);
DallasTemperature sensors(&oneWire);
ESP8266WebServer server(80);
int g;
//-----------------
void onBeatDetected()
{
;
}
void setup() {
lcd.begin(16,2);
lcd.init();
lcd.backlight();
lcd.clear();
lcd.print("Digital Oximeter");
lcd.setCursor(0, 1);
lcd.print("Tunggu Koneksi..");
delay(1000);
if (!pox.begin()) {
lcd.setCursor(0, 1);
lcd.print("Koneksi Gagal ");
for(;;);
} else {
;
}
pox.setIRLedCurrent(MAX30100_LED_CURR_24MA);
pox.setOnBeatDetectedCallback(onBeatDetected);
lcd.clear();
lcd.print("SpO2= %");
lcd.setCursor(0, 1);
lcd.print("PR = BPM");
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
Serial.begin(115200);
pinMode(16, OUTPUT);
delay(100);
Serial.println("Connecting to ");
Serial.println(ssid);
//connect to your local wi-fi network
WiFi.begin(ssid, password);
//check wi-fi is connected to wi-fi network
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected..!");
Serial.print("Got IP: "); Serial.println(WiFi.localIP());
server.on("/", handle_OnConnect);
server.onNotFound(handle_NotFound);
server.begin();
Serial.println("HTTP server started");
Serial.print("Initializing pulse oximeter..");
if (!pox.begin()) {
Serial.println("FAILED");
for (;;);
} else {
Serial.println("SUCCESS");
}
}
void loop() {
server.handleClient();
pox.update();
sensors.requestTemperatures();
g++;
if(g>5000){
g=0;
BPM = pox.getHeartRate();
SpO2 = pox.getSpO2();
bodytemperature = sensors.getTempCByIndex(0);
if((BPM<101)&&(SpO2<101)&&(bodytemperature<101)){
lcd.setCursor(5, 0);
lcd.print(SpO2);
lcd.print(" ");
lcd.setCursor(5, 1);
lcd.print(BPM);
lcd.print(" ");
}
}
Firebase.setInt("BPM", BPM);
if (Firebase.failed()) {
Serial.print("pushing /logs failed:");
Serial.println(Firebase.error());
return;
}
Firebase.setInt("SpO2", SpO2);
if (Firebase.failed()) {
Serial.print("pushing /logs failed:");
Serial.println(Firebase.error());
return;
}
Firebase.setInt("bodytemperature", bodytemperature);
if (Firebase.failed()) {
Serial.print("pushing /logs failed:");
Serial.println(Firebase.error());
return;
}
if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
bodytemperature = sensors.getTempCByIndex(0);
BPM = pox.getHeartRate();
SpO2 = pox.getSpO2();
Serial.print("BPM: ");
Serial.println(BPM);
Serial.print("SpO2: ");
Serial.print(SpO2);
Serial.println("%");
Serial.print("Body Temperature: ");
Serial.print(bodytemperature);
Serial.println("°C");
Serial.println("*********************************");
Serial.println();
tsLastReport = millis();
}
}
void handle_OnConnect() {
server.send(200, "text/html", SendHTML(BPM, SpO2, bodytemperature));
}
void handle_NotFound() {
server.send(404, "text/plain", "Not found");
}
String SendHTML(float BPM, float SpO2, float bodytemperature) {
String html = "<!DOCTYPE html>";
html += "<html>";
html += "<head>";
html += "<title>Patient Health Monitoring</title>";
html += "<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
html += "<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.2/css/all.min.css'>";
html += "<link rel='stylesheet' type='text/css' href='styles.css'>";
html += "<style>";
html += "body { background-color: #fff; font-family: sans-serif; color: #333333; font: 14px Helvetica, sans-serif box-sizing: border-box;}";
html += "#page { margin: 20px; background-color: #fff;}";
html += ".container { height: inherit; padding-bottom: 20px;}";
html += ".header { padding: 20px;}";
html += ".header h1 { padding-bottom: 0.3em; color: #008080; font-size: 45px; font-weight: bold; font-family: Garmond, 'sans-serif'; text-align: center;}";
html += "h2 { padding-bottom: 0.2em; border-bottom: 1px solid #eee; margin: 2px; text-align: left;}";
html += ".header h3 { font-weight: bold; font-family: Arial, 'sans-serif'; font-size: 17px; color: #b6b6b6; text-align: center;}";
html += ".box-full { padding: 20px; border 1px solid #ddd; border-radius: 1em 1em 1em 1em; box-shadow: 1px 7px 7px 1px rgba(0,0,0,0.4); background: #fff; margin: 20px; width: 300px;}";
html += "#media (max-width: 494px) { #page { width: inherit; margin: 5px auto; } #content { padding: 1px;} .box-full { margin: 8px 8px 12px 8px; padding: 10px; width: inherit;; float: none; } }";
html += "#media (min-width: 494px) and (max-width: 980px) { #page { width: 465px; margin 0 auto; } .box-full { width: 380px; } }";
html += "#media (min-width: 980px) { #page { width: 930px; margin: auto; } }";
html += ".sensor { margin: 12px 0px; font-size: 2.5rem;}";
html += ".sensor-labels { font-size: 1rem; vertical-align: middle; padding-bottom: 15px;}";
html += ".units { font-size: 1.2rem;}";
html += "hr { height: 1px; color: #eee; background-color: #eee; border: none;}";
html += "</style>";
//Ajax Code Start
html += "<script>\n";
html += "setInterval(loadDoc,1000);\n";
html += "function loadDoc() {\n";
html += "var xhttp = new XMLHttpRequest();\n";
html += "xhttp.onreadystatechange = function() {\n";
html += "if (this.readyState == 4 && this.status == 200) {\n";
html += "document.body.innerHTML =this.responseText}\n";
html += "};\n";
html += "xhttp.open(\"GET\", \"/\", true);\n";
html += "xhttp.send();\n";
html += "}\n";
html += "</script>\n";
//Ajax Code END
html += "</head>";
html += "<body>";
html += "<div id='page'>";
html += "<div class='header'>";
html += "<h1>Health Monitoring System</h1>";
html += "</div>";
html += "<div id='content' align='center'>";
html += "<div class='box-full' align='left'>";
html += "<h2>Sensors Readings</h2>";
html += "<div class='sensors-container'>";
//For Heart Rate
html += "<p class='sensor'>";
html += "<i class='fas fa-heartbeat' style='color:#cc3300'></i>";
html += "<span class='sensor-labels'> Heart Rate </span>";
html += (int)BPM;
html += "<sup class='units'>BPM</sup>";
html += "</p>";
html += "<hr>";
//For Sp02
html += "<p class='sensor'>";
html += "<i class='fas fa-burn' style='color:#f7347a'></i>";
html += "<span class='sensor-labels'> Sp02 </span>";
html += (int)SpO2;
html += "<sup class='units'>%</sup>";
html += "</p>";
html += "<hr>";
//For Body Temperature
html += "<p class='sensor'>";
html += "<i class='fas fa-thermometer-full' style='color:#d9534f'></i>";
html += "<span class='sensor-labels'> Body Temperature </span>";
html += (int)bodytemperature;
html += "<sup class='units'>°C</sup>";
html += "</p>";
html += "</div>";
html += "</div>";
html += "</div>";
html += "</div>";
html += "</div>";
html += "</body>";
html += "</html>";
return html;
}
I need to create simple monochromatic button, just black frame with black text (I know, with 1bit it will be ugly) on white background. Is there any method which doesn't need paintEvent to be re-implemented?
The best way is using your own style sheet.
A basic example could be the following one. In this example, we set a style with white background, black border and black text. The opposite when the user presses the button.
Depending on your requirements, you could set the style for states like disabled, checked or hover.
main.cpp
#include <QtWidgets>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtWidgets>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
};
#endif
mainwindow.cpp
#include <QtWidgets>
#include "mainwindow.h"
MainWindow::MainWindow()
{
QWidget *centralWidget = new QWidget(this);
QHBoxLayout *layout = new QHBoxLayout;
QPushButton *pushButton = new QPushButton("PushButton");
pushButton->setStyleSheet(
"QPushButton {"
" background-color: white;"
" border: 1px solid black;"
" color: black;"
" outline: none;"
"}"
"QPushButton:pressed {"
" background-color: black;"
" border: 1px solid white;"
" color: white;"
"}"
);
layout->addWidget(pushButton);
centralWidget->setLayout(layout);
setCentralWidget(centralWidget);
}
Good examples here and here.
I want to print rows of "QStandardItemModel". I use this code, It works but table is not beautiful.
I don't know how to adjust row height and I don't know how to set column widths based on the width of cells in the first row of the table.
QPrinter printer;
printer.setPageSize(QPrinter::A4);
printer.setFullPage(true);
QPrintDialog *dlg = new QPrintDialog(&printer,0);
if(dlg->exec() == QDialog::Accepted) {
QPainter painter;
if (painter.begin(&printer)) {
painter.translate(0,0);
int position = 0;
int rowCount=newMyModel->rowCount(QModelIndex());
for(int r=0;r<rowCount;r++)
{
if( position > painter.window().height()-100 )
{
printer.newPage();
position = 0;
painter.resetTransform();
painter.translate(0, 0);
}
QString html="<table style='page-break-after:always' border='1' width='100%' cellpadding =10 style='border-width: 1px;border-style: solid;border-color: #9e9e9e;width:100%'>";
index=newMyModel->index(r, 0);
QVariant prop1=index.data(MyModel::prop1);
QVariant prop2=index.data(MyModel::prop2);
'''
'''
'''
html.append(
"<tr style='background-color:red'>"
"<td style='border-width: 1px;padding:10; border-style: solid; border-color: #9e9e9e;width:16%'>"+prop1.toString()+" </td>"
"<td style='border-width: 1px;padding:10; border-style: solid; border-color: #9e9e9e;width:16%'>"+prop2.toString()+" </td>"
...
...
...);
}
html.append("</table>");
QRect rect = painter.boundingRect(painter.window(),
Qt::AlignJustify | Qt::TextWordWrap,
html);
QTextDocument doc;
doc.setHtml(html);
doc.drawContents(&painter, rect);
painter.drawRect(rect);
painter.translate(0, rect.height());
position += rect.height();
}
painter.end();
}
}
I try to draw a text on a QImage using the QTextDocument.
How to set a default ("body") style?
Currently I use a <p> tag, like this
QPainter painter(_image);
QTextDocument doc;
doc.setDefaultStyleSheet("p { color : green; background-color : black; }");
doc.setHtml("<p>test 123</p>");
doc.drawContents(&painter,_image->rect());
I would like to get rid of <p> tag
doc.setHtml("test 123");
I have tried
doc.setDefaultStyleSheet("body { color : green; background-color : black; }");
doc.setDefaultStyleSheet("{ color : green; background-color : black; }");
doc.setDefaultStyleSheet("color : green; background-color : black; ");
doc.setDefaultStyleSheet("QImage { color : green; background-color : black; }");
EDIT:
I have also tried
doc.setDefaultStyleSheet("* { color : green; background-color : black; }");
You should wrap content with <body> tag:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QTextDocument doc;
doc.setDefaultStyleSheet("body { color : green; background-color : black; }");
doc.setHtml("<body>test 123</body>");
QTextEdit textEdit;
textEdit.setDocument(&doc);
textEdit.show();
return app.exec();
}
I am generating html report with QTextDocument, my problem it comes when it should print each table on its own page, but it doesn't. I tried to use QPainter along with QTextDocument::drawContents() but this makes it show only the first page.
Another attempt was to insert a div and set its style to page-break-after:auto even it is supported by QTextDocument web engine, but this didn't work too.
void SemesterResultsReport::printDivisionStudentsNotes() {
QMap<int, int> divisionsList = SemesterResultsReport::getSelectedDivisions();
QPrinter *printer = new QPrinter(QPrinter::ScreenResolution);
printer->setFullPage(true);
printer->setResolution(90);
printer->setPaperSize(QPrinter::A4);
printer->setOrientation(QPrinter::Landscape);
printer->setPageMargins(5, 5, 5, 5, QPrinter::Millimeter);
/*printer->setOutputFormat(QPrinter::PdfFormat);
printer->setOutputFileName("sdf.pdf");*/
QPrintPreviewDialog *dlg = new QPrintPreviewDialog(printer, this);
connect(dlg, SIGNAL(paintRequested(QPrinter *)), this, SLOT(printOrder(QPrinter *)));
dlg->exec();
}
void SemesterResultsReport::printOrder(QPrinter *printer) {
QString strStream;
QTextStream out(&strStream);
QSqlQuery studentInfo, studentNotes;
QSqlRecord studentInfoRec, studentNotesRec;
QMap<int, int> selectedDivisions = SemesterResultsReport::getSelectedDivisions();
QMap<int, int>::const_iterator divisionId;
QTextDocument *document = new QTextDocument();
QTextCursor cursor(document);
QTextOption options;
options.setTextDirection(Qt::RightToLeft);
QSizeF paperSize;
paperSize.setWidth(printer->width());
paperSize.setHeight(printer->height());
document->setDefaultTextOption(options);
document->setPageSize(paperSize);
int mat_div = 0;
int level = 0;
int semester = ui.semestersList->currentText().toInt();
int school_year = 2015;
int numMaterials = 0;
// Report
out << "<!DOCTYPE html>"
<< "<html>\n"
<< "<head>"
<< "<title>ff</title>"
<< "<meta http-equiv=\"Content-Type\" content =\"text/html;charset=utf-8\" >"
<< "<style type=\"text/css\"> "
<< " html, body { margin: 5px; direction: rtl; width: 100% !important; align: right !important; float: right !important; }"
<< " *, p { font-family: \"Times New Roman\"; font-size: 16px; }"
<< " img { display: block; margin: 0 auto; }"
<< " p.title { font-weight: bold; font-size: 22px; align: center !important; }"
<< " table { border: 1; border-collapse: collapse; page-break-after:auto !important; width: 100% !important; align: right !important; float: right !important; }"
<< " th, td { border: 1px solid #000; padding: 0; align: center; page-break-inside:avoid; page-break-after:auto; }"
<< " tr { page-break-inside:avoid; page-break-after:auto !important; }"
<< " thead { display:table-header-group; }"
<< " tfoot { display:table-footer-group; }"
<< " .pagebreak { page-break-after:auto !important; } "
<< "</style>"
<< "</head>"
<< "<body>";
for (divisionId = selectedDivisions.constBegin(); divisionId != selectedDivisions.constEnd(); ++divisionId) {
mat_div = divisionId.key();
level = divisionId.value();
numMaterials = 0;
// Report header, get division materials to set as header
QStringList divisionMaterialsNames = SemesterResultsReport::getDivisionMaterialsNames(mat_div, level, school_year);
out << "<table float=\"right\" border=1 cellspacing=0 cellpadding=2>";
numMaterials = divisionMaterialsNames.size();
out << "<thead><tr bgcolor=#f0f0f0>";
for (int i = numMaterials - 1; i > -1; --i) {
out << "<th>" + divisionMaterialsNames[i] + "</th>";
}
out << "<th>" + QString("الإسم") + "</th>"
<< "<th>" + QString("اللقب") + "</th>"
<< "<th>" + QString("الرقم التسلسلي") + "</th>"
<< "</tr></thead>";
// Echo student info plus materials notes
QString fullName = ", fname, lname";
QString infoQuery = "SELECT Student.mat_stud as matStud" + fullName + " FROM Student, Class, Division WHERE Class.mat_div = Division.mat_div AND Class.mat_class = Student.mat_class AND school_year = " + QString::number(school_year) + " AND Class.level = " + QString::number(level) + " AND Division.mat_div = " + QString::number(mat_div);
studentInfo.exec(infoQuery);
studentInfoRec = studentInfo.record();
fullName.clear();
infoQuery = "SELECT Student.mat_stud as matStud FROM Student, Class, Division WHERE Class.mat_div = Division.mat_div AND Class.mat_class = Student.mat_class AND school_year = " + QString::number(school_year) + " AND Class.level = " + QString::number(level) + " AND Division.mat_div = " + QString::number(mat_div);
QString notesQuery = "SELECT materials_notes FROM Notes WHERE mat_stud IN (" + infoQuery + ") AND school_year = " + QString::number(school_year) + " AND level = " + QString::number(level) + " AND mat_div = " + QString::number(mat_div) + " AND semester = " + QString::number(semester);
studentNotes.exec(notesQuery);
studentNotesRec = studentNotes.record();
QStringList studentNotesList;
while (studentInfo.next()) {
out << "<tr>";
studentNotes.next();
studentNotesList = studentNotes.value(studentNotesRec.indexOf("materials_notes")).toString().split(",");
for (int i = 0; i < numMaterials; ++i) {
out << "<th>" + studentNotesList[i] + "</th>";
}
out << " <th>" + studentInfo.value(studentInfoRec.indexOf("lname")).toString() + "</th>"
<< " <th>" + studentInfo.value(studentInfoRec.indexOf("fname")).toString() + "</th>"
<< " <th>" + studentInfo.value(studentInfoRec.indexOf("matStud")).toString() + "</th>";
out << "</tr>";
}
// Close table tag, and insert new page, but it doesn't work
out << "</table><div style=\"page-break-after:auto !important;\"></div>";
}
// Finish report
out << "</body>"
<< "</html>";
/*
* Prepare QTextDocument
*/
document->setHtml(strStream);
document->print(printer);
// this makes only the first page printed
/*QPainter painter;
painter.begin(printer);
document->drawContents(&painter, printer->pageRect());
painter.end();*/
}